Is it safe to write code in this way?
var form = new Form();
Action callback =
() =>
{
// do something 1
};
ThreadPool.QueueUserWorkItem(
args =>
{
// do something 2
form.BeginInvoke(callback);
});
UPD I'm concerned about safety of access to the "form" variable. I use BeginInvoke method from background thread; can I be sure there won't be any read/write reordering before this moment? (that potentially can leave "form" variable in inconsistent state, from perspective of the background thread)
Yes, it looks OK. The variable form will be captured and as long as it's not null when the job on the ThreadPool executes it ought to work.
But you left out a lot of details, I assume this code is all from 1 method.
// do something 1 can acess the GUI, // do something 2 can not.
ThreadPool.QueueUserWorkItem(
args =>
{
// do something 2
form.BeginInvoke(x);
});
What actually happens here is the compiler creates a brand new class for you, and inside it there's a member variable that holds your Form instance. This class is new'd up and then passed to the ThreadPool.QueueUserWorkItem(). So yes, it's thread safe.
Related
I'm beginner in the usage of threads and in the examples that I've seen (as here and here) a new thread must be assigned to a method. But, is there a way of making that inside the method? I'm looking for something like this:
public void MyMethod()
{
//Start new thread that affects only this method
//Do stuff
//More stuff
}
Thank you.
You can start anonymous method or lambda if you don't want to create separate method.
Simplest way:
Task.Run(()=>{
// Your new thread code
});
Be aware that this creates closure and parent method variables you use in your thread will not be disposed until your thread is done. Also it's not a good practice to start a long running threads like this, because it uses thread pool.
So in this case you can do something like in the code below, or use more verbose syntax for creating tasks and specify TaskCreationOptions.LongRunning parameter.
new Thread((ThreadStart)delegate() {
// Your new thread code
}).Start();
You can put new Thread object into variable to control it later.
may I have the community's opinion here. I have an application in which I have multiple threads accessing a member of a (this) class, the class that invoked the thread itself. The problem is that when the new thread adds an element in a LinkedList member, I can see that the LinkedList's count is increased to 1 as a result of the added element, however in the main thread the changes made by the new thread was not reflected. I even passed the reference of the current object to ParameterizedThreadStart, but it's still not working.
illustration:
ParameterizedThreadStart^ pReceiveProc = gcnew ParameterizedThreadStart(this, &ActualClass::Receive);
Thread^ pReceiveThread = gcnew Thread(pReceiveProc);
pReceiveThread->Start(this); // passed the current instance
the thread method:
void Receive(Object^ pObj) {
ActualClass^ l_Cls = dynamic_cast<ActualClass^>(pObj);
l_Cls->MyLinkList->AddLast("test");
Console::WriteLine("{0}", l_Cls->MyLinkList->Count); //outputs 1
}
but if I access MyLinkList from the main thread:
void MethodMainThread(){
Console::WriteLine("{0}", MyLinkList->Count); //outputs 0
}
A static member solution is not an option.
most propably , your secondary thread gets preempted and your main thread checks for count and then secondary thread adds an object , try to use signaling , and let the main thread wait till the secondary thread completed its operation.
You can't share data between threads just like that. A simple approach to it is using the 'lock' statement. It is rather straightforward and here's a good explanation.
I have a question. Is it possible and valid, if I have an object with a method DoSomething(), if I create multiple threads for this method, will it work and would it run as a seperate thread of its own?
E.g.
public class SomeClass
{
public void DoSomething()
{
//somethings done here
}
}
public class MainProgram
{
public MainProgram()
{
InitializeComponents();
}
protected override OnStart(string[] args)
{
SomeClass sc = new SomeClass();
Thread workerOne = new Thread(() => sc.DoSomething());
workerOne.Start();
Thread workerTwo = new Thread(() => sc.DoSomething());
workerTwo.Start(); //start a new thread calling same method
}
}
I hope that kind of explains what I mean. Would this work or cause any problems?
I am writing a program that needs to almost be realtime software, I am currently deciding whether initialising a new instance of SomeClass is better or not?
Hope someone can answer. If my question's dont make sense, please comment and I'll explain further!
Thanks,
Base33
PS The code was written specifically for the example :)
Each thread has a separate call stack, so yes they can both be using the same method on the same object. And indeed, if needed each thread can (via recursion) call the same method on the same instance multiple times if you really want.
However, what might trip you up is if you are using state in that object (instance or static fields, etc, and anything related from that state). You will need to ensure your access to any shared state gives full consideration (and presumably synchronisation) to multi-threaded access.
Yes you can do that. You will however have to make sure that your member accesses within that method are thread safe.
If you mutate the state of the object you should either lock your reads and writes (not speaking of any particular mechanism) or verify that it's harmless to interupt the method at any given time and that the other call on a different thread will still work correctly
Is it possible and valid, if I have an object with a method DoSomething(), if I create multiple threads for this method, will it work and would it run as a seperate thread of its own?
Yes it is possible. In your code example, DoSomething is being called on the same instance of SomeClass. Both threads share this. You have two distinct threads but one actual object being shared.
Would this work or cause any problems?
That entirely depends on your use case. It may or may not. If objects are shared, you need to synchronize access to them.
It has no problem. I will run without any error.
It is just like creating an object and call method on this object
twice. only fact is that two occurrence of calling same method is on
different thread.
I asked the question below couple of weeks ago. Now, when reviewing my question and all the answers, a very important detail jumped into my eyes: In my second code example, isn't DoTheCodeThatNeedsToRunAsynchronously() executed in the main (UI) thread? Doesn't the timer just wait a second and then post an event to the main thread? This would mean then that the code-that-needs-to-run-asynchronously isn't run asynchronously at all?!
Original question:
I have recently faced a problem multiple times and solved it in different ways, always being uncertain on whether it is thread safe or not: I need to execute a piece of C# code asynchronously. (Edit: I forgot to mention I'm using .NET 3.5!)
That piece of code works on an object that is provided by the main thread code. (Edit: Let's assume that object is thread-safe in itself.) I'll present you two ways I tried (simplified) and have these four questions:
What is the best way to achieve what I want? Is it one of the two or another approach?
Is one of the two ways not thread-safe (I fear both...) and why?
The first approach creates a thread and passes it the object in the constructor. Is that how I'm supposed to pass the object?
The second approach uses a timer which doesn't provide that possibility, so I just use the local variable in the anonymous delegate. Is that safe or is it possible in theory that the reference in the variable changes before it is evaluated by the delegate code? (This is a very generic question whenever one uses anonymous delegates). In Java you are forced to declare the local variable as final (i.e. it cannot be changed once assigned). In C# there is no such possibility, is there?
Approach 1: Thread
new Thread(new ParameterizedThreadStart(
delegate(object parameter)
{
Thread.Sleep(1000); // wait a second (for a specific reason)
MyObject myObject = (MyObject)parameter;
DoTheCodeThatNeedsToRunAsynchronously();
myObject.ChangeSomeProperty();
})).Start(this.MyObject);
There is one problem I had with this approach: My main thread might crash, but the process still persists in the memory due to the zombie thread.
Approach 2: Timer
MyObject myObject = this.MyObject;
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.AutoReset = false; // i.e. only run the timer once.
timer.Elapsed += new System.Timers.ElapsedEventHandler(
delegate(object sender, System.Timers.ElapsedEventArgs e)
{
DoTheCodeThatNeedsToRunAsynchronously();
myObject.ChangeSomeProperty();
});
DoSomeStuff();
myObject = that.MyObject; // hypothetical second assignment.
The local variable myObject is what I'm talking about in question 4. I've added a second assignment as an example. Imagine the timer elapses after the second assigment, will the delegate code operate on this.MyObject or that.MyObject?
Whether or not either of these pieces of code is safe has to do with the structure of MyObject instances. In both cases you are sharing the myObject variable between the foreground and background threads. There is nothing stopping the foreground thread from modifying myObject while the background thread is running.
This may or may not be safe and depends on the structure of MyObject. However if you haven't specifically planned for it then it's most certainly an unsafe operation.
I recommend using Task objects, and restructuring the code so that the background task returns its calculated value rather than changing some shared state.
I have a blog entry that discusses five different approaches to background tasks (Task, BackgroundWorker, Delegate.BeginInvoke, ThreadPool.QueueUserWorkItem, and Thread), with the pros and cons of each.
To answer your questions specifically:
What is the best way to achieve what I want? Is it one of the two or another approach? The best solution is to use the Task object instead of a specific Thread or timer callback. See my blog post for all the reasons why, but in summary: Task supports returning a result, callbacks on completion, proper error handling, and integration with the universal cancellation system in .NET.
Is one of the two ways not thread-safe (I fear both...) and why? As others have stated, this totally depends on whether MyObject.ChangeSomeProperty is threadsafe. When dealing with asynchronous systems, it's easier to reason about threadsafety when each asynchronous operation does not change shared state, and rather returns a result.
The first approach creates a thread and passes it the object in the constructor. Is that how I'm supposed to pass the object? Personally, I prefer using lambda binding, which is more type-safe (no casting necessary).
The second approach uses a timer which doesn't provide that possibility, so I just use the local variable in the anonymous delegate. Is that safe or is it possible in theory that the reference in the variable changes before it is evaluated by the delegate code? Lambdas (and delegate expressions) bind to variables, not to values, so the answer is yes: the reference may change before it is used by the delegate. If the reference may change, then the usual solution is to create a separate local variable that is only used by the lambda expression,
as such:
MyObject myObject = this.MyObject;
...
timer.AutoReset = false; // i.e. only run the timer once.
var localMyObject = myObject; // copy for lambda
timer.Elapsed += new System.Timers.ElapsedEventHandler(
delegate(object sender, System.Timers.ElapsedEventArgs e)
{
DoTheCodeThatNeedsToRunAsynchronously();
localMyObject.ChangeSomeProperty();
});
// Now myObject can change without affecting timer.Elapsed
Tools like ReSharper will try to detect whether local variables bound in lambdas may change, and will warn you if it detects this situation.
My recommended solution (using Task) would look something like this:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var localMyObject = this.myObject;
Task.Factory.StartNew(() =>
{
// Run asynchronously on a ThreadPool thread.
Thread.Sleep(1000); // TODO: review if you *really* need this
return DoTheCodeThatNeedsToRunAsynchronously();
}).ContinueWith(task =>
{
// Run on the UI thread when the ThreadPool thread returns a result.
if (task.IsFaulted)
{
// Do some error handling with task.Exception
}
else
{
localMyObject.ChangeSomeProperty(task.Result);
}
}, ui);
Note that since the UI thread is the one calling MyObject.ChangeSomeProperty, that method doesn't have to be threadsafe. Of course, DoTheCodeThatNeedsToRunAsynchronously still does need to be threadsafe.
"Thread-safe" is a tricky beast. With both of your approches, the problem is that the "MyObject" your thread is using may be modified/read by multiple threads in a way that makes the state appear inconsistent, or makes your thread behave in a way inconsistent with actual state.
For example, say your MyObject.ChangeSomeproperty() MUST be called before MyObject.DoSomethingElse(), or it throws. With either of your approaches, there is nothing to stop any other thread from calling DoSomethingElse() before the thread that will call ChangeSomeProperty() finishes.
Or, if ChangeSomeProperty() happens to be called by two threads, and it (internally) changes state, the thread context switch may happen while the first thread is in the middle of it's work and the end result is that the actual new state after both threads is "wrong".
However, by itself, neither of your approaches is inherently thread-unsafe, they just need to make sure that changing state is serialized and that accessing state is always giving a consistent result.
Personally, I wouldn't use the second approach. If you're having problems with "zombie" threads, set IsBackground to true on the thread.
Your first attempt is pretty good, but the thread continued to exist even after the application exits, because you didn't set the IsBackground property to true... here is a simplified (and improved) version of your code:
MyObject myObject = this.MyObject;
Thread t = new Thread(()=>
{
Thread.Sleep(1000); // wait a second (for a specific reason)
DoTheCodeThatNeedsToRunAsynchronously();
myObject.ChangeSomeProperty();
});
t.IsBackground = true;
t.Start();
With regards to the thread safety: it's difficult to tell if your program functions correctly when multiple threads execute simultaneously, because you're not showing us any points of contention in your example. It's very possible that you will experience concurrency issues if your program has contention on MyObject.
Java has the final keyword and C# has a corresponding keyword called readonly, but neither final nor readonly ensure that the state of the object you're modifying will be consistent between threads. The only thing these keywords do is ensure that you do not change the reference the object is pointing to. If two threads have read/write contention on the same object, then you should perform some type of synchronization or atomic operations on that object in order to ensure thread safety.
Update
OK, if you modify the reference to which myObject is pointing to, then your contention is now on myObject. I'm sure that my answer will not match your actual situation 100%, but given the example code you've provided I can tell you what will happen:
You will not be guaranteed which object gets modified: it can be that.MyObject or this.MyObject. That's true regardless if you're working with Java or C#. The scheduler may schedule your thread/timer to be executed before, after or during the second assignment. If you're counting on a specific order of execution, then you have to do something to ensure that order of execution. Usually that something is a communication between the threads in the form of a signal: a ManualResetEvent, Join or something else.
Here is a join example:
MyObject myObject = this.MyObject;
Thread task = new Thread(()=>
{
Thread.Sleep(1000); // wait a second (for a specific reason)
DoTheCodeThatNeedsToRunAsynchronously();
myObject.ChangeSomeProperty();
});
task.IsBackground = true;
task.Start();
task.Join(); // blocks the main thread until the task thread is finished
myObject = that.MyObject; // the assignment will happen after the task is complete
Here is a ManualResetEvent example:
ManualResetEvent done = new ManualResetEvent(false);
MyObject myObject = this.MyObject;
Thread task = new Thread(()=>
{
Thread.Sleep(1000); // wait a second (for a specific reason)
DoTheCodeThatNeedsToRunAsynchronously();
myObject.ChangeSomeProperty();
done.Set();
});
task.IsBackground = true;
task.Start();
done.WaitOne(); // blocks the main thread until the task thread signals it's done
myObject = that.MyObject; // the assignment will happen after the task is done
Of course, in this case it's pointless to even spawn multiple threads, since you're not going to allow them to run concurrently. One way to avoid this is by not changing the reference to myObject after you've started the thread, then you won't need to Join or WaitOne on the ManualResetEvent.
So this leads me to a question: why are you assigning a new object to myObject? Is this a part of a for-loop which is starting multiple threads to perform multiple asynchronous tasks?
What is the best way to achieve what I want? Is it one of the two or another approach?
Both look fine, but...
Is one of the two ways not thread-safe (I fear both...) and why?
...they are not thread safe unless MyObject.ChangeSomeProperty() is thread safe.
The first approach creates a thread and passes it the object in the constructor. Is that how I'm supposed to pass the object?
Yes. Using a closure (as in your second approach) is fine as well, with the additional advantage that you don't need to do a cast.
The second approach uses a timer which doesn't provide that possibility, so I just use the local variable in the anonymous delegate. Is that safe or is it possible in theory that the reference in the variable changes before it is evaluated by the delegate code? (This is a very generic question whenever one uses anonymous delegates).
Sure, if you add myObject = null; directly after setting timer.Elapsed, then the code in your thread will fail. But why would you want to do that? Note that changing this.MyObject will not affect the variable captured in your thread.
So, how to make this thread-safe? The problem is that myObject.ChangeSomeProperty(); might run in parallel with some other code that modifies the state of myObject. There are basically two solutions to that:
Option 1: Execute myObject.ChangeSomeProperty() in the main UI thead. This is the simplest solution if ChangeSomeProperty is fast. You can use the Dispatcher (WPF) or Control.Invoke (WinForms) to jump back to the UI thread, but the easiest way is to use a BackgroundWorker:
MyObject myObject = this.MyObject;
var bw = new BackgroundWorker();
bw.DoWork += (sender, args) => {
// this will happen in a separate thread
Thread.Sleep(1000);
DoTheCodeThatNeedsToRunAsynchronously();
}
bw.RunWorkerCompleted += (sender, args) => {
// We are back in the UI thread here.
if (args.Error != null) // if an exception occurred during DoWork,
MessageBox.Show(args.Error.ToString()); // do your error handling here
else
myObject.ChangeSomeProperty();
}
bw.RunWorkerAsync(); // start the background worker
Option 2: Make the code in ChangeSomeProperty() thread-safe by using the lock keyword (inside ChangeSomeProperty as well as inside any other method modifying or reading the same backing field).
The bigger thread-safety concern here, in my mind, may be the 1 second Sleep. If this is required in order to synchronize with some other operation (giving it time to complete), then I strongly recommend using a proper synchronization pattern rather than relying on the Sleep. Monitor.Pulse or AutoResetEvent are two common ways to achieve synchronization. Both should be used carefully, as it's easy to introduce subtle race conditions. However, using Sleep for synchronization is a race condition waiting to happen.
Also, if you want to use a thread (and don't have access to the Task Parallel Library in .NET 4.0), then ThreadPool.QueueUserWorkItem is preferable for short-running tasks. The thread pool threads also won't hang up the application if it dies, as long as there is not some deadlock preventing a non-background thread from dying.
One thing not mentioned so far: The choice of threading methods depends heavily on specifically what DoTheCodeThatNeedsToRunAsynchronously() does.
Different .NET threading approaches are suitable for different requirements. One very large concern is whether this method will complete quickly, or take some time (is it short-lived or long-running?).
Some .NET threading mechanisms, like ThreadPool.QueueUserWorkItem(), are for use by short-lived threads. They avoid the expense of creating a thread by using "recycled" threads--but the number of threads it will recycle is limited, so a long-running task shouldn't hog the ThreadPool's threads.
Other options to consider are using:
ThreadPool.QueueUserWorkItem() is a convienient means to fire-and-forget small tasks on a ThreadPool thread
System.Threading.Tasks.Task is a new feature in .NET 4 which makes small tasks easy to run in async/parallel mode.
Delegate.BeginInvoke() and Delegate.EndInvoke() (BeginInvoke() will run the code asynchronously, but it's crucial that you ensure EndInvoke() is called as well to avoid potential resource-leaks. It's also based on ThreadPool threads I believe.
System.Threading.Thread as shown in your example. Threads provide the most control but are also more expensive than the other methods--so they are ideal for long-running tasks or detail-oriented multithreading.
Overall my personal preference has been to use Delegate.BeginInvoke()/EndInvoke() -- it seems to strike a good balance between control and ease of use.
I need to run 5 algorithms parallely each takes an image as input and gives image as output. After each of these is done, I need to display the 5 output images. I'm using Asynchronous Callback using delegates for this task.
So, I created 5 delegates for these 5 algos and calling them like algo1Delegate.BeginInvoke().
Algorithms are running fine and giving the output too. I'm facing 2 problems in displaying these images.
For displaying images, I created a class ImageViewer (windows form with picturebox element in it).
//ImageViewer constructor
ImageViewer(Image img, String Title)
{
this.pictureBox1.Image = img;
this.Text = Title;
}
I'm displaying images like this:
void showImage(Image image, String title)
{
ImageViewer imageviewer = new ImageViewer(image, title);
imageviewer.Show();
}
Since I need to display an image after algo. I'm passing new AsyncCallback(showImage) delegate for each of these BeginInvoke() as 3rd parameter
private void showImage(IAsyncResult iasycResult)
{
MessageBox.Show("white" + Thread.CurrentThread.ManagedThreadId);
// Retrieve the `caller` delegate.
AsyncResult asycResult = (AsyncResult)iasycResult;
caller = (Algo1Delegate)asycResult.AsyncDelegate;//### PROBLEM!!!
// Retrieve the string Title that is passed in algodelegate.BeginInvoke().
string title = (string)iasycResult.AsyncState;
Image outputImage = caller.EndInvoke(iasycResult);
showImage(outputImage, title);
}
I think you can see the problem in the above callback function. it only works for Algo1 for other 4 alog's it needs to be casted to Algo2Delegate , Algo3Delegate etc.. because asycResult.AsyncDelegate is of type object. How can I solve this problem? How can I make it work for others too?
The imageViewer window is getting "unresponsive". I don't understand why? ImageViewer object is initialized and displayed on the same thread for each of these algos. Why is it becoming unresponsive.
Any other alternative solutions?
PS: I cannot declare one delegateType for all the algos since there are some differences in input parameters.
EDIT:
Well, I got enough inputs for my 1st and 3rd questions. I used separate callbacks for each of these algorithms. My 2nd problem is still unsolved. I changed the constructor of ImageViewer() Just to check if they are executing on two different threads:
public ImageViewer(Image img, String title)
{
InitializeComponent();
if (pictureBox1.InvokeRequired) MessageBox.Show("You must Invoke()");
else MessageBox.Show("No need of Invoke()");
this.pictureBox1.Image = img;
this.Text = title + " : Image Viewer";
}
in every case it says No need of Invoke(). I don't understand what is the problem. Can any one please address this too? I don't get any execptions also. Just the window is becoming unresponsive. I checked if algorithms are causing any trouble. But no, they arent.
I can't think of a clean solution to your problem. You'd have to write fugly code like this:
AsyncResult result = (AsyncResult)iresult;
if (result.AsyncDelegate is AsyncDelegate1) {
(result.AsyncDelegate as AsyncDelegate1).EndInvoke(iresult);
}
else if (result.AsyncDelegate is AsyncDelegate2) {
(result.AsyncDelegate as AsyncDelegate2).EndInvoke(iresult);
}
//etc...
ComputationResult answer = result.AsyncState as ComputationResult;
Yuck. You really ought to have an individual callback method for each delegate type. A generic method cannot help here, the constraint cannot be a delegate type. A lambda in the BeginInvoke method call doesn't look that much better:
var task1 = new AsyncDelegate1(Compute1);
var result1 = new ComputationResult("task1");
task1.BeginInvoke(42, result1,
new AsyncCallback((ia) => {
AsyncResult result = ia as AsyncResult;
(result.AsyncDelegate as AsyncDelegate1).EndInvoke(ia);
CommonCallback(result.AsyncState as ComputationResult);
}),
result1);
Nah. I'd tackle this by using only one delegate type. The WaitCallback type is suitable, although mis-named, you should write little helper classes that store the arguments for the delegate target so you can pass it through the WaitCallback.state argument.
Your second problem is induced because you are creating the ImageViewer instance in the callback method. The callback executes on a threadpool thread, not the UI thread. InvokeRequired returns false because the PictureBox control was created on the threadpool thread. This threadpool thread is however not suitable to display UI components, it doesn't pump a message loop. And has the wrong apartment state. And it terminates too soon.
InvokeRequired will return the proper value (true) when you use a Control that was created on the UI thread. Your main startup form for example. Or Application.OpenForms[0]. There's little point in using InvokeRequired however, you know for a fact that the callback executes on the wrong thread. Just use BeginInvoke directly. The invoked method should create the ImageViewer instance.
You are well on your way re-inventing the BackgroundWorker class. It does exactly what you are trying to do. But takes care of the gritty details of getting the RunWorkerCompleted event fired on the correct thread. You ought to consider it.
You should substitute the delegates with a consistent hierarchy with the common methods you need.
AsyncCallbackClass caller = (AlgoDelegate)asycResult.AsyncState;
Image img = caller.DoCallBack(iAsyncResult);
then you have a hierarchy with:
class AsyncCallback1 : AsyncCallbackClass
{
Image DoCallBack(IAsyncResult result)
{
// Call specific callback with specific parameters
}
}
class AsyncCallback2 : AsyncCallbackClass
{
Image DoCallBack(IAsyncResult result)
{
// Call specific callback with specific parameters
}
}
Basically you'll be constructing your callbacks as a hierarchy of classes so that the "signature" of the main method is the same (a method that takes an IAsyncResult) and returns an image, but the way each "delegate" (which is now a full class) implements the call is unique for each implementation.
Take a look at Replace Delegate with inheritance.
Edit: From the msdn page.
true if the control's Handle was
created on a different thread than the
calling thread (indicating that you
must make calls to the control through
an invoke method); otherwise, false.
I assume you're creating the ImageBox in the ImageViewer, and the ImageViewer is being created in the callback so, by definition, the ImageBox has been created by the same thread and therefore does not need to be invoked.
Can you wrap your calls into lambda expression and then, have a method that starts the delegate:
private void run(Action<Image,Image> delegate, Image inputImage)
{
delegate.BeginInvoke(inputImage, // all the callback stuff here );
}
But then call your run method with lambdas:
run(image => algo1(image, otherVar, otherVar2));
run(image => algo2(image, otherVar, otherVar2, otherVar3, otherVar4));
and so on
I was doing something similar some months ago, I was using ThreadPool:
http://msdn.microsoft.com/en-us/library/3dasc8as%28VS.80%29.aspx
http://www.switchonthecode.com/tutorials/csharp-tutorial-using-the-threadpool
It is managing the threads for you and is fairly easy to use for tasks which are not requiring complex multithreading.
#1. You have five delegates but you have defined a common callback method for each. So you will have a problem finding out what delegate actually has completed. One way is to have different callback method for every delegate.
#2 You should not update the UI from a different thread than on what it was created. If it is true, we use Control.Invoke to make sure the call is marshaled to the UI thread.
MethodInvoker updateImageViewer = delegate
{
ImageViewer imageviewer = new ImageViewer(image, title);
imageviewer.Show();
};
if (this.pictureBox1.InvokeRequired)
this.pictureBox1.Invoke(updateImageViewer);
else
updateImageViewer();