WPF报错:The Solution of “The calling thread cannot access this object beacuse a different thread owns

The actual solution looks like this:
insert image description here

Recently, I am using WPF to make a program about UI performance, which needs to monitor a specified folder and then display the newly added pictures in it.

    最简单的一行代码如下,此代码是为界面上的TextBlock元素指定值,如下:

this.lstText.Text = "Test";
Because the controls of the UI layer and the logic layer are not controlled by the same thread, it will cause an error during loading, and the following error message will be thrown: The calling thread cannot access this object because a different thread owns It.
translated into Chinese is: [The calling thread cannot access this object because another thread owns the object.

A more common solution is to use WPF's Dispatcher.Invoke method, only the thread on which the Dispatcher is created can directly access the DispatcherObject. To access the DispatcherObject from a thread other than the thread on which it was created, call Invoke or BeginInvoke on the Dispatcher associated with the DispatcherObject. Subclasses of DispatcherObject that need to enforce thread safety can enforce thread safety by calling VerifyAccess on all public methods. This guarantees that the calling thread is the thread on which the DispatcherObject was created.

code show as below:

lstText[i].Dispatcher.Invoke(new Action(() =>
{
this.lstText.Text = “Test”;
}));

In this way, the above-mentioned problems can be solved.

error:The calling thread cannot access this object because a different thread owns it解决方法

Dao Tong

Released at 2014-03-04 18:08:49

6413
Favorite
WPF The calling thread cannot access this object because another thread owns it.

One: WPF threading model.
Unless you are already very familiar with the WPF architecture and multi-threaded development, we often encounter such an exception when dealing with WPF:

Because other threads own this object, the calling thread cannot access it. (The calling thread cannot access this object because a different thread owns it)

In WPF, there are two threads inherently, one thread is used to render the UI, and the other thread is to manage the UI (this we call the UI thread). It is said that the animation effect of android is not as good as that of iphone. It is because the priority of the drawing and rendering thread of iphone is very high. As long as there is an operation related to animation, such as sliding a menu, then this animation will be arranged at the highest priority. Level operation, so as to ensure smooth animation. I haven't studied it in depth, so the above description may not be quite correct technically, but it can be understood in this way. Probably the same idea in WPF. The UI thread creates those controls defined in XAML or in c#, and owns them, and for the protection of the UI, other threads cannot access the things in the UI thread. If we create a new thread, then in this thread If you modify a Button.Content defined in xaml or in the main thread, you will get this exception.

In the process of IM development, when using the agsXMPP library, agsXMPP has many events, such as XmppClientConnection.OnStateChanged event, OnError event, etc. We will use many event processing functions. One thing to note here is that when these events are triggered, When the code is executed into the event processing function, the thread that executes the code is often not the main thread (here "often" I don't know if it is used correctly, anyway, none of the things I encounter are executed in the main thread), that is to say, If you write such code in the event processing function at this time: button1. content="something", an exception will be thrown because other threads own this object, so the calling thread cannot access it. When we debug the code in visual studio, we can see whether the currently executing code is the main thread or another thread: if the thread column does not indicate "main thread", then the thread currently executing the code is not the main thread.

At this time, what if we must access the control in other threads? This requires passing the Dispatcher. Most of the controls in WPF inherit from DispatcherObject, so they have the Dispatcher property. I won’t write what this Dispatcher is, because I don’t know, but in a superficial sense, it is for the thread it belongs to. Such an object of work scheduling, or a steward of threads, or an intermediary. If you want to access the control of this thread outside the thread (or other thread) that owns a certain control, you can only process it through the Dispatcher of this control. Dispatcher has two methods: Invoke and BeginInvoke, which are used to open to the outside world. An opportunity to access controls owned by the thread to which this Dispatcher belongs. For example, I want to access the Button of the main thread in other threads:

Copy code
private void OnEventFired(object sender, MouseButtonEventArgs e)

{ btn.Dispatcher.Invoke( new Action( delegate { button1.Content = "some text "; })); } Copy the code Assuming that OnEventFired is being executed by other threads, the code uses the Invoke method of btn.Dispatcher to execute an (anonymous ) function, which is to set button1.content. The former of Invoke and BeginInvoke is instant call and asynchronous call



Supongo que te gusta

Origin blog.csdn.net/weixin_41883890/article/details/128804826
Recomendado
Clasificación