how can i make a user control to run on its own thread ?
e.g. by following code in a user control , coz user control uses main app thread it make main thread to sleep
Thread.Sleep(TimeSpan.FromMinutes(2));
User controls need to run on the UI thread because that is a restriction in the Windows API. If you try and use Windows Forms controls from another thread you will get an exception.
You can run other code in another thread, but use the UI thread to update the controls. You can use BackgroundWorker for this. Or you can use the InvokeRequired and Invoke or BeginInvoke methods on the control instance to have it execute code on the UI thread.
You mention you want to use a mutex lock. A mutex is to avoid having multiple threads access a resource at the same time. If all your code is running in the same thread then you don't need a lock at all.
Objects don't really "run" themselves - methods are executed on a thread.
Now if you want a particular method to execute in a different thread, you need to either create a new thread, use the threadpool explicitly, or use something which uses the threadpool for you - such as BackgroundWorker.
What are you doing when you want to sleep for two minutes? Could you avoid sleeping by just setting a timer to fire (in the UI thread) in two minutes instead? If this is part of some long-running process, you should use BackgroundWorker or some other way of executing on a different thread, but with the control itself still handling updates and events on the UI thread.
Related
BackgroundWorker can access UI controls directly, but Thread's cannot, Why?
Isn't BackgroundWorker a thread? If it isn't, what is it? Also, why is direct accessing restricted? Is restricting direct access Microsoft's choosen way for doing something or must it be done this way?
According to MSDN, "The BackgroundWorker class allows you to run an operation on a separate, dedicated thread."
BackgroundWorker acutally uses Form.Invoke() to switch control to the main UI thread to report progress. In the fact BackgroundWorker is just a helper class that you could easily write yourself, it uses a second thread to do the work but then it switches to the main UI thread to access GUI.
Also from MSDN: "You can listen for events that report the progress of your operation and signal when your operation is completed." This means that the background operation runs on a separate thread and you can't access GUI from that thread. But you can access GUI controls from progress event because it is raised on the main UI thread. Whenever you call BackgroundWorker.ReportProgress() on the worker thread, it raises BackgroundWorker.ProgressChanged event on the main thread.
Also, you ask why GUI cannot be accessed from other threads. It is because whole Windows GUI subsystem is not thread safe. As far as I know this is pretty normal in other platforms (outside Windows) as well, so it definitely isn't Microsoft specific. It is probably from historical reasons and probably has something to do with code efficiency. (A thread safe GUI would be slower.) But I can't provide any strong information source as a reference.
A background worker will throw a cross-thread exception just as a new thread would. A backgroundworker is just a fancy way to start a new thread.
If you are using the ProgressChanged event then you do not need to invoke it because there is some .NET magic behind the scenes doing it for you.
More information on background workers:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.100).aspx
I am currently working with threading and backgroundworker in c#. The problem im having is that this. Say i have a main thread for user interaction and a worker thread to process txt files(various editing operations). Then after the backgroundthread runs its contents once, i have a timer start that performs another set of operations. I want these new operations that the timer runs ever x minutes to be run in the same background thread without running the previous txt related operations it ran before the timer started. How can this be done?
You should just use a System.Timers.Timer, which will run its callback on a thread pool thread.
It shouldn't matter which specific thread you run on (as long as it's not the UI thread).
If, for some reason, it does matter (eg, if you're using a single-threaded COM object), you'll need to make a dedicated thread that waits for things to do using a thread-safe queue of delegates.
You want to use an Event Driven method to execute function calls on your worker thread from your UI thread. The way to accomplish this is using BeginInvoke, you can read more about how to use it here: http://www.dreamincode.net/forums/topic/35616-cross-thread-communication-in-c%23/
Add a while loop to the end of your background worker:
while(!stop) { Thread.Sleep(yourIntervalinMilliseconds); ... }
I'd create a stop bool somewhere that the thread looks at when you want it to kick out.
I am a bit confused about how GUI can be used in multi-threaded applications.
I hear there is a thing called the UI thread. Which I assume is my main executing thread at the startup of the application.
I also hear (though I am not 100% on this) that doing UI stuff on other (non UI) threads is a very bad idea.
So, if I create a separate thread and I want to call MyForm myForm = new MyForm(); myForm.ShowDialog(); in it, what changes do I need to make for that to be "safe"?
Also, I have had some people tell me that events are spun out on a different thread. (Though I am not sure I believe this.) If they are, then I am confused. I can open a dialog (ie myForm.ShowDialog() in an event and nothing truly horrible happens. (Maybe this depends on if the event delegate was called with Invoke or BeginInvoke?)
Here are a few bits of info that may help you out. What you're saying about working with UI on non UI threads isn't just a bad idea, you'll get an exception. Meaning, if you create a Form in the main thread, and then spawn off a background thread to do some processing and then want to update the Form in that background thread, it'll throw an exception. In your example though, where you create the Form in a background thread, you should be OK. I'd question your design, but it won't blow up AS LONG AS YOU ONLY TOUCH THE UI IN THAT SAME THREAD.
As for events, events handlers are executed on the same thread they were raised on. Meaning, if you have a Form on one thread that spawns off some work on another thread that raises events, but before doing so, you hook into this event on the Form thread, you need to be careful not to touch the UI directly in the event handlers, because those event handlers are being called on the background thread.
Finally, the way to correctly manipulate the UI from a background thread, is by calling Invoke and passing in a delegate that does the UI work you want. HTH
In WinForms you need to call UI-things on UI thread, you always can check on what thread you currents are getting InvokeRequired of UI-control.
void ApplyUiChanges()
{
if(this.InvokeRequired)
{
this.Invoke(new Action(ApplyUiChanges));
return;
}
// UI stuff here...
}
In WPF techinic is alike. But instead of using InvokeRequired you should ask CheckAccess() of DispatcherObject (All UI-controls derive from it)
void ApplyUiChanges()
{
if (!dispatcherObject.CheckAccess())
{
dispatcherObject.Dispatcher.Invoke(DispatcherPriority.Send, new Action(ApplyUiChanges));
return;
}
// UI stuff here...
}
Also you can take a look at Async CTP, which might be useful. But it's only CTP, not a release yet.
Another way to handle UI-thread communication is to use PostSharp. Write (or copy-paste) GuiThreadAttribute. After that, you'll be able to use such semantics:
[GuiThread]
void ApplyUiChanges()
{
// UI stuff here...
}
From what I've experienced, "UI thread" is a misnomer. There isn't one single thread that handles all of the UI for an application. To keep things simple, it's generally a good idea to have UI on one thread, but nothing stops you from spawning another thread, and creating new controls on that thread and showing them to the user. What's important is that control properties are only changed on the thread it was created on. As mentioned by another person, you can see if you are currently on that thread by looking at the Control.InvokeRequired property.
If you are on a thread that isn't the one you want a new form to run on and you don't have the luxury of being on the context of a control that is created on the thread you want, then you'll have to get a reference to the System.Threading.SynchronizationContext of the thread you want it to be on (I usually achieve this by storing a reference of System.Threading.SynchronizationContext.Current from the main thread in a static variable, but this can only be done after at least one control has been created on the thread). This object will allow you to run a delegate on its home thread.
I had to do this once in a Windows application that also hosted a WCF service, and UI needed to be launched from the service, but I wanted it on the same thread as the rest of the UI.
HTH,
Brian
In WinForms applications there is only a single thread which is the UI thread. You don't want to block this thread with long operations so that the UI is always responsive. Also you shouldn't update any UI elements from any thread other than the UI thread.
I always use a BackgroundWorker if I want to perform any lengthy operations from the UI. The major benefit of BackgroundWorker is that it can report progress and report that it is complete via ProgressChanged and RunWorkerCompleted. These 2 events occur in the UI thread thus you can update any UI element safely without the need to use InvokeRequired and Invoke.
The MSDN article: How to: Make Thread-Safe Calls to Windows Forms Controls
says we should use async delegate to make the call. But why does the async delegate make the call safe?
Windows controls use the Component Object Model (COM) single-threaded apartment (STA) model because those underlying controls are apartment-threaded. Furthermore, many of the controls use the message pump for many operations. This model says that all function calls to each control must be on the same thread that created the control. Invoke (and BeginInvoke and EndInvoke) marshals method calls to the proper thread.
From Bill Wagner's More Effective C#. Item 16. Understand Cross-Thread Calls in Windows Forms and WPF
You'll call control.BeginInvoke() or control.Invoke() and that method will take care of inserting your delegate in the GUI dispatch thread safely, so a bit later on your delegate will be processed and executed in the GUI thread and not the thread you'r in
The bottom line is this: You shouldn't update the UI Controls from a thread other than the one on which the control was created (UI / Main Thread). Otherwise you may see some unpredictable behavior.
If you need to update the UI from a worker thread (other than the main thread) you need to switch back to the UI Thread before updating the UI.
The article suggests using
IsInvokeRequired (which returns true if the current thread is not the one in which UI was created.) and Invoke(delegate) which runs the delegate on the correct/UI thread. This is useful when you want to update the UI in between the async process. e.g. update progress on the UI.
BackgroundWorker which executes registered handlers to its DoWork event async. on a worker thread and runs the registered handlers to its RunWorkerCompleted event on the calling thread. This is ideal if you want to update the UI with something after the async task has completed. e.g. post a Done indication on the UI
Because, windows forms controls are designed in that way, so they can be accessed only from within he thread, which owes them. And the async delegate, when used correctly, makes the call safe.
The actual answer to the given question is contained in the second paragraph of the given MSDN article =)
Access to Windows Forms controls is not inherently thread safe. If you have two or more threads manipulating the state of a control, it is possible to force the control into an inconsistent state. Other thread-related bugs are possible, such as race conditions and deadlocks. It is important to make sure that access to your controls is performed in a thread-safe way.
You should check whether you can access control immediately, without indirection ( checking the InvokeRequired property ), if you can't, you should access it asynchronously ( very simplified explanation: the system will wait until it can safely access a control )
I have thread that monitor the status of the device( using i/o ). This will fire the event to several UI (Forms/Dialogs..) parts about the connection status(Connected, Disconnected, Fault). Based on this status, the forms and dialogs are destroyed, created , enabled and disabled.
My Problem :
I getting Cross-Thread exception because the thread doing the operations like Dispose the from, create the from .... . I using smart client, forms and dialogs are part of the WorkItemController and i just terminating that.
I don't want u use Invoke or BeginInvoke . I want this thread to continue only monitoring the status. SO that this thread has to give its control to the main thread and the main thread will close the form or create the form.
Just i want how to shift the control from one thread to another. Is any way is there?
The best solution is to use Invoke to switch back to your mainthread.
or if you can use global variables shared between the main thread and your background thread, but this means your main thread should check the variables in a loop and this may hang GUI.
Or use System.Windows.Forms.Timer as it executes in the main thread.