need advice in multythread
Hi,
If i want to use WriteableBitmapEx in a multi thread app, which a single thread is responsible for rendering an image in real-time, very much like rendering a game, but not exactly like that. just like one.
The problem is the main UI thread is different than rendering thread and i'll get the exception by wpf which says owner thread only can access the bitmap. if I create the WriteableBitmap in the render thread, then UI cannot access it and vice versa.
I was wondering if you guys have any suggestion for my case?
Thanks
I have the same problem, i want to draw a writeableBitmap by multiple threads to increase the draw speed, but seem like it cannot work
Seems wpf have a strict diplomacy in cross thread access, which every call is checked with DispatcherObject.VerifyAccess() and DispatcherObject.CheckAccess(), even when it is not needed.
The way this library for example draws a line, is first create an instance of BitmapContext struct ,which is not public structure. This structure is not thread sensitive, but when a new instance of BitmapContext is creating in the constructor it tries to access the WriteableBitmap's dependency properties which i think that causes the error.
There are two solutions i think. source code should be edited:
- use
Dispatcher.Invoke()when reading theDependencyPropertys ofWriteableBitmap - mark the
BitmapContextas public (~~which is currently internal~~ it is alread public ) and make same extension methods fromWriteableBitmaplikeWriteableBitmap.DrawLineAaforBitmapContexttoo. i mean add a new method ofBitmapContext.DrawLine()to the library. this also do not work unless edit some code int theBitmapContextconstructor.
first solution need least effort, but not so much general second solution need more effort but general, also i think improves the performance as for every line draw it do not creates am instance of BitmapContext. I think it could be pull request. @reneschulte, could you please let us know your opinion about this? this is more like a architectural plan. If it is OK with you, I can do the code and make the pull request... Thanks
after exploring the code, i've found a way:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WriteableBitmapExMultythreadExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
WriteableBitmap Bitmap;
public MainWindow()
{
InitializeComponent();
var w = 500;
var h = 500;
Bitmap = BitmapFactory.New(w, h);
bmp.Source = Bitmap;
var ctx = Bitmap.GetBitmapContext();
var thr = new Thread(DrawLine); thr.Start(); thr.Join();
//DrawLine();
ctx.Dispose();
//Bitmap.AddDirtyRect(new Int32Rect(0, 0, w, h));
}
public void DrawLine()
{
Bitmap.DrawLineAa(20, 20, 400, 400, Colors.Black, 2);
}
}
}
if you call var ctx = Bitmap.GetBitmapContext(); in the main thread, you can do edits in another threads and finally when you call ctx.Dispose(); changes would be applied.
seems the WritebleBitmapEx is managing the multy threaded access with some extra cost.
I think better to let user handle the complexity, as discussed in #92.