• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

C#: passing GUI data to new tasks

Spungo

Diamond Member
I'm trying to get into asynchronous tasks, and I'm having trouble understanding what thread has access to what data. In particular, I'm trying to pass data from the GUI (WPF) to new tasks that are performing CPU-intense work. If a checkbox is checked, do something a certain way. If a checkbox is not checked, do it a different way. In simple terms it's like this:

The following code does not work. It says PublishAllCheckBox.IsChecked is owned by a different thread.
Code:
// all of this is in partial class MainWindow

private Task PublishEverythingAsync()
{
   return Task.Factory.StartNew( () => PublishEverything(PublishAllCheckBox.IsChecked));
}


The following code does work:
Code:
// all of this is in partial class MainWindow

private Task PublishEverythingAsync()
{
   bool? temporaryVariable = PublishAllCheckBox.IsChecked;
   return Task.Factory.StartNew( () => PublishEverything(temporaryVariable));
}


Using synchronous tasks for CPU-intense work freezes the GUI, so I assume the GUI and my code are the same thread. If that's the case, why are the tasks started by Task.Factory.StartNew() not able to get a variable from the GUI? Why do I need that new temporaryVariable?
 
Using synchronous tasks for CPU-intense work freezes the GUI, so I assume the GUI and my code are the same thread.

Yes.

If that's the case, why are the tasks started by Task.Factory.StartNew() not able to get a variable from the GUI? Why do I need that new temporaryVariable?

Using Task.Factory causes the work to be done in another thread via thread pool maintained by the Task Parallel Library.

UI elements can very easily end up being updated or accessed from multiple threads doing different things. Rather than trying to implement complex locking to avoid race conditions, or having to deal with deadlocks, many GUI libraries simply say that UI objects can only be accessed from the UI thread.
 
To marshall messages between the threads and the GUI thread you need to use the dispatcher. Here is the MSDN link.

https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke(v=vs.110).aspx

EDIT - Before the next question comes. Which is: What is a delegate? I will just say this. A delegate is a template of a function. It is not a function itself, just the way the function looks to the program. Like a class interface. But for a function. So you will need to create a template (or delegate) of a function, then pass a function that matches that delegate to the Dispatcher invoke function to get a response, etc.
 
Last edited:
UI elements can very easily end up being updated or accessed from multiple threads doing different things. Rather than trying to implement complex locking to avoid race conditions, or having to deal with deadlocks, many GUI libraries simply say that UI objects can only be accessed from the UI thread.
I can understand not allowing one to write to the UI from anywhere, but reading from it seems fairly harmless. I guess the two can't be separated.


To marshall messages between the threads and the GUI thread you need to use the dispatcher.

EDIT - Before the next question comes. Which is: What is a delegate? I will just say this. A delegate is a template of a function. It is not a function itself, just the way the function looks to the program. Like a class interface. But for a function. So you will need to create a template (or delegate) of a function, then pass a function that matches that delegate to the Dispatcher invoke function to get a response, etc.
I'm thinking maybe I should try writing a new version of my program from scratch that is needlessly parallel everywhere. Dragging and dropping files into the listbox should start a new async task, do some stuff, and try to return data to the listbox. By the time I'm done writing it, I'll have a better understanding of these things.
 
Back
Top