开发者

Multithreaded access to the WPF GUI in C#

I'm trying to create a custom, in-house application that is going to access other internal systems which broadcast their names and IP addresses via UDP. I'm trying to create a multi-threaded dialog that polls for UDP messages every 500 ms for 15 seconds, parses the UDP messages and then adds the names of the detected systems to a ListBox in the dialog, updating it in real time. I've already got the UDP scanning code tested and done, the only problem is updating the ListBox across threads. Any time I try to access the ListBox's Items or ItemSource properties, I get a System.InvalidOperationException : "The calling thread cannot access this object because a different thread owns it."

The relevant stack trace portion:

   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.ItemsControl.set_ItemsSource(IEnumerable value)

This occurs regardless of whether I'm using an ObservableCollection (I know, has nothing to do with the collection type), a HashSet or any other object. Can anybody help开发者_开发百科 me with accessing the GUI across different threads ?


You can't access the gui safely from other threads. All calls have to be dispatched via a call to Invoke to be executed on the main thread. This is a legacy hang-up that Windows has been saddled with for years.

Here's a snippet of code that should get you started... (found here: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/360540eb-d756-4434-86f9-a3449f05eb55/ )

if(textbox.Dispatcher.CheckAccess())
{
   // The calling thread owns the dispatcher, and hence the UI element
   textbox.AppendText(...);
}
else
{
   // Invokation required
   textbox.Dispatcher.Invoke(DispatcherPriority.Normal, [delegate goes here]);
}

There is additional clarification here: http://channel9.msdn.com/forums/TechOff/251835-WPF-Invoke-and-Anonymous-delegates/


As Andrew already said, you should synchronize the access to GUI across the threads (it's just the way it is - you can't do much about it).

However, Dispatcher is a WPF-specific synchronization mechanism. If you'd like to stick to a more general approach, then take a look at System.Threading.SynchronizationContext class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜