Error: Must Create Dependencysource on Same Thread as the Dependencyobject Even by Using Dispatcher

Error: Must create DependencySource on same Thread as the DependencyObject even by using Dispatcher

BitmapImage is DependencyObject so it does matter on which thread it has been created because you cannot access DependencyProperty of an object created on another thread unless it's a Freezable object and you can Freeze it.

Makes the current object unmodifiable and sets its IsFrozen property to true.

What you need to do is call Freeze before you update Image:

bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
bi.Freeze();

Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);

as pointed out by @AwkwardCoder here is Freezable Objects Overview

Must create DependencySource on same Thread as DependencyObject

The SolidColorBrush is a Freezable which is a derived DispatcherObject. DispatcherObjects have thread affinity - i.e it can only be used/interacted with on the thread on which it was created. Freezables however do offer the ability to freeze an instance. This will prevent any further changes to the object but it will also release the thread affinity. So you can either change it so that your property is not storing a DependencyObject like SolidColorBrush and instead just store the Color. Or you can freeze the SolidColorBrush that you are creating using the Freeze method.

Must create DependencySource on same Thread as the DependencyObject even by using Dispatcher WPF

When loading a BitmapImage from a Stream, you would usually close the Stream as soon as possible and make sure the BitmapImage is loaded immediately, by setting BitmapCacheOption.OnLoad.

private static BitmapImage ToBitmapImage(Bitmap bitmap)
{
var start = 420;
var end = 1920 - 2 * 420;

var croppedBitmap = bitmap.Clone(
new System.Drawing.Rectangle(start, 0, end, 1080),
bitmap.PixelFormat);

var bi = new BitmapImage();

using (var ms = new MemoryStream())
{
croppedBitmap.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);

bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = ms;
bi.EndInit();
}

bi.Freeze();

return bi;
}

Must create DependencySource on same Thread as the DependencyObject when changing SelectedItem

Set the SelectedItem property back on the UI thread once the Task has finished:

public void OnLoad()
{
StartRunning(this, null);
Task.Factory.StartNew(new Action(() =>
{
Load();
})).ContinueWith(task =>
{
SelectedItem = Results[0];
StopRunning(this, null);
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}

You can only access a UI element on the thread on which it was originally created so if your UpdatePoints() method accesses any control you must call this method on the UI thread.

Must create DependencySource on same Thread as the DependencyObject using await/async

You can't generally create a control on one thread and then interact with it one another one, but a frozen freezable can be shared across threads so you can try to freeze the Model3D before you return it:

private Model3D Load(string path)
{
var model = importer.Load(path);
model.Freeze();
return model;
}

Please refer to MSDN for more information about freezables.

Must create DependencySource on same Thread as the DependencyObject. when binding Background

Whatever code is directly accessing your UI, you can only run on the UI thread.
Use a dispatcher to run it there, e.g.:

Application.Current.Dispatcher.Invoke(() =>
{
// the code that's accessing UI properties
});

Must create DependencySource on same Thread as the DependencyObject When Create GridView

As the error says Dependency Property and its corresponding binding have to be created on same thread. It can't be set on different threads. Put the creation of grid on UI dispatcher too. Since your ListView View DP is created on UI thread, hence its source property i.e. GridView should also be on UI thread.

Application.Current.Dispatcher.Invoke((Action)(delegate
{
GridView grid = new GridView();
grid.Columns.Add((GridViewColumn)myresourcedictionary["gridDirFileName"]);
grid.Columns.Add((GridViewColumn)myresourcedictionary["gridDirFileType"]);
grid.Columns.Add((GridViewColumn)myresourcedictionary["gridDirFileDataModified"]);
grid.Columns.Add((GridViewColumn)myresourcedictionary["gridDirFileSize"]);
ListViewOp.View = grid
}));

How to create a BitmapImage buffer in background thread on C#?

You're creating something on a non ui thread that by default has thread affinity.

Luckily though, a bitmapimage inherits from freezable.
See the inheritance chain:

https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapimage?view=net-5.0

Inheritance:
Object
DispatcherObject
DependencyObject
Freezable
Animatable
ImageSource
BitmapSource
BitmapImage

If you call .Freeze() on a freezable then you can pass it between threads.

https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/freezable-objects-overview?view=netframeworkdesktop-4.8

From there:

What Is a Freezable?

A Freezable is a special type of object that has two states: unfrozen and frozen. When unfrozen, a Freezable appears to behave like any other object. When frozen, a Freezable can no longer be modified.

A Freezable provides a Changed event to notify observers of any modifications to the object. Freezing a Freezable can improve its performance, because it no longer needs to spend resources on change notifications. A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.



Related Topics



Leave a reply



Submit