Open epsi1on opened 4 weeks ago
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:
Dispatcher.Invoke()
when reading the DependencyProperty
s of WriteableBitmap
BitmapContext
as public (WriteableBitmap
like WriteableBitmap.DrawLineAa
for BitmapContext
too. i mean add a new method of BitmapContext.DrawLine()
to the library. this also do not work unless edit some code int the BitmapContext
constructor.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.
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 theWriteableBitmap
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