I'm having one thread that generates GUI elements in wpf. A canvas is there to draw objects (rectangles and so on ...)
This wpf thread calls another thread let's name it the calculation thread. This thread calculates the size and position and so on of the elements to be shown in the canvas.
I want to have these two parts (GUI and calculatio) run in different threads. The "calculation thread" is based on a library without references to wpf functionality.
Now I want to show intermediate data of the calculation thread displayed by the wpf thread.
I'm doing it that way:
The calc-thread fires an event (DataReady) that is implemented by the wpf-thread:
void MyRegStringObject_DataReady()
{
if (DebugMode)
MyDrawingBoard.DrawRegElements();
}
The problem now is, that an error is thrown: "calling thread cannot access this object because a different thread owns it"
There are some answered question here in stackoverflow referring to this error but none of them can help in my case.
The function DrawRegElements() wants to clear the canvas object (among other things):
curCanvas.Children.Clear();
At this position in the code the error is thrown.
It seems that the function MyRegStringObject_DataReady triggered by an event from the calc-thread is owened by the calc-thread also. But it is defined in class that the wpf-thread is based on.
How can I solve this problem? Does anyone have any idea?
By the way:
The calc-thread is called this way:
CalcElements = Task.Factory.StartNew<bool>(MyRegStringObject.CalcRegElements);
When the thread is finished I defined:
CalcElements.ContinueWith((FinishCalcRegElements) =>
{
MyDrawingBoard.DrawRegElements();
}, CancellationToken.None, TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
No problem with that. Everythins runs perfect. The function defined in ContinueWith seems to be owened by the wpf-thread.
Error message is straightforward, you are trying access an UI element from a now owning thread. Delegate this work to WPF Dispatcher which is associated with Main UI thread, which would post all messages from worker thread to UI thread:
Application.Current.Dispatcher.BeginInvoke((ThreadStart)delegate
{
MyDrawingBoard.DrawRegElements();
});
To be sure that you are using correct Dispatcher, associated with the Main UI thread, you can pass it as a parameter to the worker thread code, so just pass Dispatcher.Current from Main UI thread, otherwise calling Dispatcher.CurrentDispatcher in the worker thread will initialize a new instance associated with a calling worker thread. Or just use Application.Current.Dispatcher which would reference the Main UI thread's Dispatcher.
PS:
But it is defined in class that the wpf-thread is based on
This is wrong assumption, classes itself are not related to any thread. Concrtete class instances are. So you can create UI/non-UI related classes either in UI or worker thread.
Also important point in which thread DataReady event has been fired?
Related
In the book Programming C#, it has some sample code about SynchronizationContext:
SynchronizationContext originalContext = SynchronizationContext.Current;
ThreadPool.QueueUserWorkItem(delegate {
string text = File.ReadAllText(#"c:\temp\log.txt");
originalContext.Post(delegate {
myTextBox.Text = text;
}, null);
});
I'm a beginner in threads, so please answer in detail.
First, I don't know what does context mean, what does the program save in the originalContext? And when the Post method is fired, what will the UI thread do?
If I ask some silly things, please correct me, thanks!
EDIT: For example, what if I just write myTextBox.Text = text; in the method, what's the difference?
What does SynchronizationContext do?
Simply put, SynchronizationContext represents a location "where" code might be executed. Delegates that are passed to its Send or Post method will then be invoked in that location. (Post is the non-blocking / asynchronous version of Send.)
Every thread can have a SynchronizationContext instance associated with it. The running thread can be associated with a synchronization context by calling the static SynchronizationContext.SetSynchronizationContext method, and the current context of the running thread can be queried via the SynchronizationContext.Current property.
Despite what I just wrote (each thread having an associated synchronization context), a SynchronizationContext does not necessarily represent a specific thread; it can also forward invocation of the delegates passed to it to any of several threads (e.g. to a ThreadPool worker thread), or (at least in theory) to a specific CPU core, or even to another network host. Where your delegates end up running is dependent on the type of SynchronizationContext used.
Windows Forms will install a WindowsFormsSynchronizationContext on the thread on which the first form is created. (This thread is commonly called "the UI thread".) This type of synchronization context invokes the delegates passed to it on exactly that thread. This is very useful since Windows Forms, like many other UI frameworks, only permits manipulation of controls on the same thread on which they were created.
What if I just write myTextBox.Text = text; in the method, what's the difference?
The code that you've passed to ThreadPool.QueueUserWorkItem will be run on a thread pool worker thread. That is, it will not execute on the thread on which your myTextBox was created, so Windows Forms will sooner or later (especially in Release builds) throw an exception, telling you that you may not access myTextBox from across another thread.
This is why you have to somehow "switch back" from the worker thread to the "UI thread" (where myTextBox was created) before that particular assignment. This is done as follows:
While you are still on the UI thread, capture Windows Forms' SynchronizationContext there, and store a reference to it in a variable (originalContext) for later use. You must query SynchronizationContext.Current at this point; if you queried it inside the code passed to ThreadPool.QueueUserWorkItem, you might get whatever synchronization context is associated with the thread pool's worker thread. Once you have stored a reference to Windows Forms' context, you can use it anywhere and at any time to "send" code to the UI thread.
Whenever you need to manipulate a UI element (but are not, or might not be, on the UI thread anymore), access Windows Forms' synchronization context via originalContext, and hand off the code that will manipulate the UI to either Send or Post.
Final remarks and hints:
What synchronization contexts won't do for you is telling you which code must run in a specific location / context, and which code can just be executed normally, without passing it to a SynchronizationContext. In order to decide that, you must know the rules and requirements of the framework you're programming against — Windows Forms in this case.
So remember this simple rule for Windows Forms: DO NOT access controls or forms from a thread other than the one that created them. If you must do this, use the SynchronizationContext mechanism as described above, or Control.BeginInvoke (which is a Windows Forms-specific way of doing exactly the same thing).
If you're programming against .NET 4.5 or later, you can make your life much easier by converting your code that explicitly uses SynchronizationContext, ThreadPool.QueueUserWorkItem, control.BeginInvoke, etc. over to the new async / await keywords and the Task Parallel Library (TPL), i.e. the API surrounding the Task and Task<TResult> classes. These will, to a very high degree, take care of capturing the UI thread's synchronization context, starting an asynchronous operation, then getting back onto the UI thread so you can process the operation's result.
I'd like to add to other answers, SynchronizationContext.Post just queues a callback for later execution on the target thread (normally during the next cycle of the target thread's message loop), and then execution continues on the calling thread. On the other hand, SynchronizationContext.Send tries to execute the callback on the target thread immediately, which blocks the calling thread and may result in deadlock. In both cases, there is a possibility for code reentrancy (entering a class method on the same thread of execution before the previous call to the same method has returned).
If you're familiar with Win32 programming model, a very close analogy would be PostMessage and SendMessage APIs, which you can call to dispatch a message from a thread different from the target window's one.
Here is a very good explanation of what synchronization contexts are:
It's All About the SynchronizationContext.
It stores the synchronization provider, a class derived from SynchronizationContext. In this case that will probably be an instance of WindowsFormsSynchronizationContext. That class uses the Control.Invoke() and Control.BeginInvoke() methods to implement the Send() and Post() methods. Or it can be DispatcherSynchronizationContext, it uses Dispatcher.Invoke() and BeginInvoke(). In a Winforms or WPF app, that provider is automatically installed as soon as you create a window.
When you run code on another thread, like the thread-pool thread used in the snippet, then you have to be careful that you don't directly use objects that are thread-unsafe. Like any user interface object, you must update the TextBox.Text property from the thread that created the TextBox. The Post() method ensures that the delegate target runs on that thread.
Beware that this snippet is a bit dangerous, it will only work correctly when you call it from the UI thread. SynchronizationContext.Current has different values in different threads. Only the UI thread has a usable value. And is the reason the code had to copy it. A more readable and safer way to do it, in a Winforms app:
ThreadPool.QueueUserWorkItem(delegate {
string text = File.ReadAllText(#"c:\temp\log.txt");
myTextBox.BeginInvoke(new Action(() => {
myTextBox.Text = text;
}));
});
Which has the advantage that it works when called from any thread. The advantage of using SynchronizationContext.Current is that it still works whether the code is used in Winforms or WPF, it matters in a library. This is certainly not a good example of such code, you always know what kind of TextBox you have here so you always know whether to use Control.BeginInvoke or Dispatcher.BeginInvoke. Actually using SynchronizationContext.Current is not that common.
The book is trying to teach you about threading, so using this flawed example is okayish. In real life, in the few cases where you might consider using SynchronizationContext.Current, you'd still leave it up to C#'s async/await keywords or TaskScheduler.FromCurrentSynchronizationContext() to do it for you. But do note that they still misbehave the way the snippet does when you use them on the wrong thread, for the exact same reason. A very common question around here, the extra level of abstraction is useful but makes it harder to figure out why they don't work correctly. Hopefully the book also tells you when not to use it :)
The purpose of the synchronization context here is to make sure that myTextbox.Text = text; gets called on the main UI thread.
Windows requires that GUI controls be accessed only by the thread they were created with. If you try assign the text in a background thread without first synchronizing (through any of several means, such as this or the Invoke pattern) then an exception will be thrown.
What this does is save the synchronization context prior to creating the background thread, then the background thread uses the context.Post method execute the GUI code.
Yes, the code you've shown is basically useless. Why create a background thread, only to immediately need to go back to the main UI thread? It's just an example.
SynchronizationContext basically is a provider of callback delegates' execution. It is responsible for ensuring that the delegates are run in a given execution context after a particular portion of code (encapsulated inside a Task object in .Net TPL) in a program has completed its execution.
From technical point of view, SC is a simple C# class that is oriented to support and provide its function specifically for Task Parallel Library objects.
Every .Net application except for console applications has a tailored implementation of this class based on the specific underlying framework, eg: WPF, WindowsForm, Asp Net, Silverlight, etc.
The importance of this object is bound to the synchronization between results returning from asynchronous execution of code, and the execution of dependent code that is waiting for results from that asynchronous work.
And the word "context" stands for execution context. That is, the current execution context where that waiting code will be executed- namely the synchronization between async code and its waiting code happens in a specific execution context. Thus this object is named SynchronizationContext.
It represents the execution context that will look after syncronization of async code and waiting code execution.
To the Source
Every thread has a context associated with it -- this is also known as the "current" context -- and these contexts can be shared across threads. The ExecutionContext contains relevant metadata of the current environment or context in which the program is in execution. The SynchronizationContext represents an abstraction -- it denotes the location where your application's code is executed.
A SynchronizationContext enables you to queue a task onto another context. Note that every thread can have its own SynchronizatonContext.
For example: Suppose you have two threads, Thread1 and Thread2. Say, Thread1 is doing some work, and then Thread1 wishes to execute code on Thread2. One possible way to do it is to ask Thread2 for its SynchronizationContext object, give it to Thread1, and then Thread1 can call SynchronizationContext.Send to execute the code on Thread2.
SynchronizationContext provides us a way to update a UI from a different thread (synchronously via the Send method or asynchronously via the Post method).
Take a look at the following example:
private void SynchronizationContext SyncContext = SynchronizationContext.Current;
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(Work1);
thread.Start(SyncContext);
}
private void Work1(object state)
{
SynchronizationContext syncContext = state as SynchronizationContext;
syncContext.Post(UpdateTextBox, syncContext);
}
private void UpdateTextBox(object state)
{
Thread.Sleep(1000);
string text = File.ReadAllText(#"c:\temp\log.txt");
myTextBox.Text = text;
}
SynchronizationContext.Current will return the UI thread's sync context. How do I know this? At the start of every form or WPF app, the context will be set on the UI thread. If you create a WPF app and run my example, you'll see that when you click the button, it sleeps for roughly 1 second, then it will show the file's content. You might expect it won't because the caller of UpdateTextBox method (which is Work1) is a method passed to a Thread, therefore it should sleep that thread not the main UI thread, NOPE! Even though Work1 method is passed to a thread, notice that it also accepts an object which is the SyncContext. If you look at it, you'll see that the UpdateTextBox method is executed through the syncContext.Post method and not the Work1 method. Take a look at the following:
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread.Sleep(1000);
string text = File.ReadAllText(#"c:\temp\log.txt");
myTextBox.Text = text;
}
The last example and this one executes the same. Both doesn't block the UI while it does it jobs.
In conclusion, think of SynchronizationContext as a thread. It's not a thread, it defines a thread (Note that not all thread has a SyncContext). Whenever we call the Post or Send method on it to update a UI, it's just like updating the UI normally from the main UI thread. If, for some reasons, you need to update the UI from a different thread, make sure that thread has the main UI thread's SyncContext and just call the Send or Post method on it with the method that you want to execute and you're all set.
Hope this helps you, mate!
This example is from Linqpad examples from Joseph Albahari but it really helps in understanding what Synchronization context does.
void WaitForTwoSecondsAsync (Action continuation)
{
continuation.Dump();
var syncContext = AsyncOperationManager.SynchronizationContext;
new Timer (_ => syncContext.Post (o => continuation(), _)).Change (2000, -1);
}
void Main()
{
Util.CreateSynchronizationContext();
("Waiting on thread " + Thread.CurrentThread.ManagedThreadId).Dump();
for (int i = 0; i < 10; i++)
WaitForTwoSecondsAsync (() => ("Done on thread " + Thread.CurrentThread.ManagedThreadId).Dump());
}
I know that simplest way to update a label from another thread is:
void DoSomething()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(DoSomething));
} else
{
// Do Something
}
}
My question is if instead of the if that require to update the GUI from another thread is it possible to change back to the main thread and update the GUI from there ?
Actually, the simplest way to do this is
Invoke(new MethodInvoker(DoSomething));
if you call it from another thread for sure, ie. if you know, that InvokeRequired will always be true.
Also, you could use a WinForms Timer to poll for changes of, say, a text field. This timer runs in the GUI thread. That is a pretty good solution if you have hundreds of events per second. Or at least "a lot of". This way you don't have too many switches to the GUI thread (which always take considerable amount of time).
Of course its possible ... you can use class called Dispatcher (System.Windows.Threading). The main purpose of this class is to dispatch "requests/calls" on thread ... and for gui thread there is instance of such dispatcher available for all controls. You can find this instance as member of your Window for example ...
The catch is that you using dispatcher alraedy (in code you posted) in some way ... if you call Invoke inside Form this default/gui dispatcher is used. And "IF" is there for reducing count of invocation from gui thread itself.
It works like "am i in ui thread? No? Then give dispatcher request of calling this same method on UI thread! ... Am i in UI Thred? Yes! Ok, i am doing something."
If you are 100% sure that you call this form other than UI thread, you can throw away that IF and just call dispatcher directly.
MyForm.Dispatcher.Invoke( mydelegate, params[] )
Or using some lambda instead of delegate or MethodInvoker ...
MyForm.Dispatcher.BeginInvoke( (Action)(()=>{ textbox.text = result; }), null);
And at all ... you can store (in form.load event for example) reference to UI Dispatcher to use in different class (some working class doing stuff on other )
If you creating some bigger UI stuff, my suggest for better UI and easier handling stuff like this is: ... consider some study of WPF and MVVM pattern and property change notifications.... it will give you very strong tool with "self updated" and very scalable UI and layers between datas, working threads and UI.
This is my first post here as actually i usually solve all my issue with the awesome
post database you can find here. But I'm actually stuck right now:
I'm working on a project following the MVVM including a COM object.
As I read during my research, I understand that the COM object is only accessible from the thread which created it. My COM object implements the following interface
interface IComUpdate
{
void Update();
}
So when I create my COM object, each time there is an update (I dont know when, its random) the COM Server will call the Update() of the COM object class I did implement.
My goal was to create a different thread, naming a COM object thread, where the COM object exist independantly of my UI Thread, so everytime there is an update, I handle it in a different thread than the UI Thread.
Actually it is working:
At the Beginning of my ViewModel I create a collection of a specific object.
This object, lets call it ModelObj, is part of the model and defines a static constructor in which the application, apart from initializing some variables, creates and starts a new thread for the COM object:
Thread t = new System.Threading.Thread(() =>
{
System.Threading.Thread.CurrentThread.Name = "Thread of COM Object";
IComUpdate myComObj;
myComObj = (IComUpdate)Activator.CreateInstance(blabla);
Application.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
It actually works very well, in the Update() implementation of my COM object, I actually see that the thread is the one just created and not the UI thread.
Now the issue is this: this ModelObj I create implements the INotifyPropertyChanged interface.
My thinking was the following: each time the COM object receives an update, I handle data from the COM object thread, and update some property of my ModelObjinstance from this thread, so these properties will then raise the property change of my ModelObj and the UI thread will update the User Interface.
If the UI update takes too much time, I might miss some Update() to appear on the screen but the COM object will have them recorded in my ModelObj instance so it is not very important that the UI catch all the updates, I just didnt want the COM object to have to wait for the UI to be updated to be called again.
I read tons of posts and thought then that my RaisePropertyChanged("property") would fail.
Actually even in the COM object's thread, the RaisePropertyChanged successfully executes, so tracing my code, I see it switches to my ViewModel assembly where I do
// Here I'm still in the thread of my COM object!
base.NotifyOfPropertyChange<string>(() => this.property)
and then the UI Update.
Note: I'm using Caliburn Micro for binding between my View in WPF and my ViewModel.
So I can't trace after this base.NotifyOfPropertyChange<string>(() => this.property). Maybe Caliburn handles the thread switch, this is not really my issue.
What I can say is that my COM object thread waits for the UI to update to get to the next instruction after my RaisePropertyChanged("property"), so it's exactly the same as if the UI thread did the whole work.
I want my COM object thread to update my ModelObj which will send to send the UI a message to update (because some fields of this ModelObj have changed) and continue immediatly, without knowing if the UI actually updates or not.
Does someone got an idea about this behaviour?
Thank you very much.
####UPDATE####
Thanks everyone for such quick answers.
I did actually as Zdeslav Vojkovic suggested :
You should always update GUI from GUI thread
For completeness here is how I did:
Because my View is full WPF with no code behind i dont have any controls or form to be call BeginInvoke from, so in the static constructor of my ModelObj, I built an invisible Control from the UI Thread just to be able to call BeginInvoke on it.
So i declared it :
public static Control mInvokeControl;
delegate void MyDelegate();
private MyDelegate _NotifyDelegate;
and then did this in the static constructor of my Object:
mInvokeControl = new Control();
mInvokeControl.CreateControl();
in the normal constructor i Initialize the delegate this way:
_NotifyDelegate = new MyDelegate(this.NotifyByInvoke);
Then after i just use it this way:
ModelObj.mInvokeControl.BeginInvoke(this._NotifyDelegate );
With the method being:
public void NotifyByInvoke()
{
RaisePropertyChanged("Update");
}
Everything works fine !
the COMObj is only accessible from the thread which created it
this is not true. It depends on objects apartment model, but usually you can access it from any thread and it will be either called on same thread or marshaled to proper thread.
I belive that your problem is that you update GUI from background thread which is a major no-no. You should always update GUI from GUI thread. When you update your model object, it still happens on background thread and event of INotifyPropertyChanged interfaces fires on that thread.
You need to synchronize model update to GUI thread by using something like this (WinForms, not WPF - in WPF you should use frm.Dispatcher.BeginInvoke but the problem is the same):
private delegate void ExecuteActionHandler(Action action);
public static void ExecuteOnUiThread(this Form form, Action action)
{
if (form.InvokeRequired) { // we are not on UI thread
// Invoke or BeginInvoke, depending on what you need
// but you said ' and continue immediatly' so BeginInvoke it is
form.BeginInvoke(new ExecuteActionHandler(ExecuteOnUiThread), action);
}
else { // we are on UI thread so just execute the action
action();
}
}
There is another question with similar problem and I have provided additional details there.
I do not know how much data you process, or how much time it takes to perform the GUI part. You may also consider to use locked queues. You can use a queue within your ModelObj to enqueue new tasks by it. This you do with everything you get. Then you may have a timer thread (on the GUI thread).
Here you just check the locked queue, whether there is some new data to display on the GUI. You may dequeue the full list here locally. Then you can also check, whether there is more than one data to display on one component. This way you can skip updates, where you already have newer updates.
And you skip the time for invoking the gui thread to perform the action. You can do several GUI updates at once. If you have too much things to do, you may dequeue only up to a specific number of items to let the GUI react on user interactions. However, you need to check that the queue is not constantly growing.
I wrote some C# code and in it I initiate a class by placing it in its own thread so it doesnt freeze up my GUI from where I initiate it:
This is from my Form Class:
Execute_Recipe execute;
execute = new Execute_Recipe(XCoordinatesList, YCoordinatesList, Zref, Voltref,
widget, record, filename);
Thread executethread = new Thread(new ThreadStart(execute.RunRecipe));
And then in my Execute Class I create a new class to record the data. This is from my execute class:
record1 = new Record_Recipe(XCoordinateList1, YCoordinateList1, Zref1, Voltref1, filename1);
And finally in my record class I send the data to a new form. To be displayd. So in the end all of the sub classes I initiate are all created within this thread. I know the structure is absolutley crazy right now, the software is deep in its development stage, but here is my question:
How can I keep BOTH Form Classes in their own threads while having all the execution and recording of my procedure in its own thread?
Do I create 1 thread for my execution, 1 thread for my recording, and a backgrounworker for my displaying? and then talk between threads? (from what I understand talking between threads is not easy)
I am only an intermediate programmer at best and I thank you in advance if you able / willing to help with this problem.
Talking between threads is very easy in C#
yourform.BeginInvoke((MethodInvoker)delegate()
{
yourform.button.Text = "new label";
//More stuff here
});
kind of construct can be used from a worker thread to updated the UI thread. If you are creating lot of non UI threads that have smaller lifetime consider using a ThreadPool instead.
For simple ui updates also look at INotifyPropertyChanged that lets you updated data bound controls easily.
The thread you call Application.Run() on is the thread that must do all the GUI stuff. The Windows.Forms.Control base class has an Invoke() method that allows a delegate to be called whenever the GUI thread is idle (a Form is such a Control). There are quite a few other mechanisms in .NET to communicate between threads.
Communicating to a non-GUI thread is a bit getting used to, but there are quite a few options. An example of for instance using the WaitHandle is as follows:
receiving thread waits for a signal
sending thread writes data
sending thread sets signal
receiving thread reads data and performs the task
Usually one thread ("the main thread") leads and the others either wait for work, or are created, do the work and are destroyed afterwards.
I suggest you check the System.Threading namespace on MSDN and see what's available. Also http://www.albahari.com/threading/ seems to cover it all.
I use the XmlSerializer of C# to save and load all models of my application to a file. Because these file operations can take some time, I want do this serialization/deserialization process in a different thread. To do this, I used a delegate and the "BeginInvoke" operation.
The problem is that when all objects are deserialized that they are created by another thread and that all variables in these objects cannot be accessed by the GUI thread.
I know how to access an object from a different thread (by using the Dispatcher.invoke() method) but using this technique to access each variable is not an option in my application.
Is there a solution or easier way to serialize and deserialize objects in a different thread?
Edit:
When all objects are deserialized, the model notifies the view to create UI objects from the deserialized models.
//In the Model:
//when the deserialize operation is ready this handler is executed (not the GUI thread)
void ProjectLoaded(object sender, EventArgs e)
{
ProjectLoadedEventArgs projectLoadedEventArgs = e as ProjectLoadedEventArgs;
m_models = projectLoadedEventArgs.SerializedData.Models;
Notify(null);
}
//In the view:
public void Update(Object o)
{
model.Angle.... -> RIGHT VALUE!!!
Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
ResetCanvas();
model.Angle... -> ERROR: The calling thread cannot access this object because a different thread owns it.
}));
}
Deserializing thread has to store objects in some well known to UI thread place. Remember You will have to come up with some synchronization mechanism between threads.
I think I know why You have problems (I read comment to other answer). You deserialize and then notice UI that object is ready. You probably do sth like
UIComponent.DeserializationFinished(). In this method You modify the UI which is not allowed.
[Edit]
Since you've added the exception ("The calling thread cannot access this object because a different thread owns it") in the comment below, it's now clear that GUI controls are being accessed from a non GUI thread. If you search for this on StackOverflow, you will see that it's the direct consequence of refusing to use Dispatcher.Invoke.
I am afraid that you can do only two things:
The preferred way: Use Dispatcher.Invoke to invoke the async deserialization callback on a GUI thread (I realize you've said it's not an option, but it's actually the best way to do it). Remember that Dispatcher.Invoke doesn't access deserialized objects in any special way, it only invokes the callback handler on a GUI thread:
// your async callback
public void ObjectWasDeserialized(IAsyncResult result)
{
_dispatcher.Invoke(new Action<IAsyncResult>(UpdateSomeControl), result);
}
Don't use async callbacks at all, but a Future pattern as described below. But that forces you to poll the result from a GUI thread, which is a bad thing.
It doesn't matter what thread creates an object, its data is still accessible by other threads. What is not recommended is accessing GUI controls from a different thread.
What you probably need is a thread-safe way to signal the GUI thread that an object is ready to be accessed. That can be implemented as a Future object (as explained in this article by Ayende).
Your background thread should create a wrapper around your object, which also contains a ManualResetEvent set to false. After the object has been deserialized successfully, it should signal the event (ManualResetEvent.Set()). UI thread which wants to access the object will have to do it through a property which blocks on this same event until it's signaled. That's logical, since you cannot guarantee that the object will be ready anytime the GUI thread wishes it.
[Edit] Found the article with an implementation. First part is what I was talking about, and ends by defining the InThe class. The part which follows, however, is not necessary at all, and I don't recommend it.
Using the code provided by Ayende, you would have something like:
// a thread (it can even be a GUI thread) requests a future result
Future<SomeObject> future = InThe.Future<SomeObject>(() => Deserialize(file));
// later, in the GUI thread, you access the future wrapper directly
SomeObject result = future.Value; // this will block the calling thread until
// result is ready