I currently have a thread that listens for data from the network and then runs rules on it. I then want to pass the data to the GUI. I am worried about having a deadlock in the GUI. I cant figure out were to put the mutexes on the GUI side. I am also using c# and dotnet 3.5.
What I have come up with is
1) Using a timer to create an event and dump the thread. Worried about performance.
2) Use an intermediary event to copy the data to GUI.
3) Dig in and figure out thread safe way of using GUI.
What do you think is best way to proceed?
Edit: Here is the solution I am using. I pass in the changed element and then protect the big object with a mutex. I use helper function to switch threads using InvokeRequired then BeginInvoke with a delegate. Pulled from reading the answers and then following links until reaching Threading in Windows Forms by Jon Skeet.
delegate void UInt32ParameterDelegate(UInt32 n);
public void UpdateLocation(UInt32 n)
{
if (InvokeRequired)
{
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n });
return;
}
// Must be on the UI thread if we've got this far
this.engine.location.UpdateBusy.WaitOne();
// do the work in here
this.engine.location.UpdateBusy.ReleaseMutex();
}
Synchronization is very easy in Windows Forms. You can call Control.Invoke() in the background thread. The thread will stall until the delegate has finished running on the UI thread. No sync required at all.
If stalling the thread is a problem, use Control.BeginInvoke(). You'll have to protect the object(s) you pass to the delegate with a lock if the thread might alter them while it continues running. That's rarely the case in a producer-consumer scenario, the thread can simply create new objects.
Do make sure that you don't Invoke() too often. Do it more frequently than about 1000 times per second and the UI thread will stop pumping Windows messages, being bogged down by handling the invoke requests. Since it is human eyes you're trying to please, invoking more than about 25 times per second is just wasted effort. Pool intermediate results in a collection object.
I hope I understand your problem correctly.
After the background thread reads the data and does whatever it wants, it should use Invoke to call a method on the GUI thread. That method would update anything that should be updated in the GUI.
Never read from the network on the GUI thread. It's only a matter of time before your application runs during a network outage and your GUI hangs as a result. This will really frustrate your users.
In your situation I think the best approach is to have a background thread complete the read operation. Then take the resulting data and move it back to the GUI thread via a SynchronizationContext Post or Send method.
you should just pass an event from your network thread to your UI thread.
then cross threads using begininvoke so you don't get a cross thread exception.
Need help getting info across a UI thread and another thread in C#
You could use a backgroundworker that will process the datareading in a background thread and when it's done you can end the backgroundworker triggering it's RunWorkerCompletedEventHandler. In the RunWorkerCompletedEventHandler you can update your GUI thread with the result.
Isn't easier to just throw a delegate who raise an event that inform the form to refresh itself?
Related
I'm building a WPF application. I'm doing some async communication with the server side, and I use event aggregation with Prism on the client. Both these things results in new threads to be spawned which are not the UI thread. If I attempt to do "WPF operations" on these callback and event handler threads the world will fall apart, which it now has started doing.
First I met problems trying to create some WPF objects in the callback from server. I was told that the thread needed to run in STA mode. Now I'm trying to update some UI data in a Prism event handler, and I'm told that:
The caller cannot access this thread because a different thread owns it.
So; what's the key to getting things right in WPF? I've read up on the WPF Dispatcher in this MSDN post. I'm starting to get it, but I'm no wizard yet.
Is the key to always use Dispatcher.Invoke when I need to run something which I'm not sure will be called on the UI thread?
Does it matter if it actually was called on the UI thread, and I do Dispatcher.Invoke anyway?
Dispatcher.Invoke = synchronously. Dispathcher.BeginInvoke = async?
Will Dispatcher.Invoke request the UI thread, and then stop to wait for it? Is it bad practice and risk of less responsive programs?
How do I get the dispatcher anyway? Will Dispatcher.CurrentDispatcher always give me the dispatcher representing the UI thread?
Will there exist more than one Dispatcher, or is "Dispatcher" basically the same as the UI thread for the application?
And what's the deal with the BackgroundWorker? When do I use this instead? I assume this is always async?
Will everything that runs on the UI thread (by being Invoked) be run in STA apartment mode? I.e. if I have something that requires to be run in STA mode - will Dispatcher.Invoke be sufficient?
Anyone wanna clearify things for me? Any related recommendations, etc? Thanks!
Going over each of your questions, one by one:
Not quite; you should only invoke onto the UI thread when necessary. See #2.
Yes, it does matter. You should not just automatically Invoke everything. The key is to only invoke onto the UI thread if necessary. To do this, you can use the Dispatcher.CheckAccess method.
That is correct.
Also correct, and yes, you do run the risk of less responsive programs. Most of the time, you are not going to be looking at a severe performance hit (we're talking about milliseconds for a context switch), but you should only Invoke if necessary. That being said, at some points it is unavoidable, so no, I would not say it is bad practice at all. It is just one solution to a problem that you will encounter every now and then.
In every case I have seen, I have made due with Dispatcher.CurrentDispatcher. For complex scenarios, this may not be sufficient, but I (personally) have not seen them.
Not entirely correct, but this line of thinking will not do any harm. Let me put it this way: the Dispatcher can be used to gain access to the UI thread for the application. But it is not in and of itself the UI thread.
BackgroundWorker is generally used when you have a time-consuming operation and want to maintain a responsive UI while running that operation in the background. Normally you do not use BackgroundWorker instead of Invoke, rather, you use BackgroundWorker in conjunction with Invoke. That is, if you need to update some UI object in your BackgroundWorker, you can Invoke onto the UI thread, perform the update, and then return to the original operation.
Yes. The UI thread of a WPF application, by definition, must be running in a single-threaded apartment.
There's a lot to be said about BackgroundWorker, I'm sure many questions are already devoted to it, so I won't go into too much depth. If you're curious, check out the MSDN page for BackgroundWorker class.
I am writing a client server application that works like this:
Form1 loads and creates ServerHost. ServerHost is started to listen for TcpClient connections, on connected and accepted, ServerHost spawns a thread by way of ThreadPool.QueueUserWorkItem(DoWork, client);
Within the DoWork() thread, I want to update Winform Controls on Form1.
This is achieved by having events in ServerHost such as ServerHost.SomethingHappened. When something happened in DoWork(), it raises the event and the Form1.Handler is called to update the winforms control.
This set up gives me cross-thread operation error.
Is use of Control.Invoke and Control.InvokeRequired healthy? I am not good at threads, and MSDN is saying to use BackgroundWorker, but I can't see how to do it here. Any advice to change the structure to avoid using Invoke in this set up?
Control.Invoke is highly questionable, and Control.InvokeRequired is downright toxic.
If at all possible, use the new async/await support, and you won't need to explicitly marshal back to the UI thread. Also, use Task.Run instead of ThreadPool.QueueUserWorkItem for background work.
The problem with Control.Invoke is that it ties your library to a specific UI (WinForms). Capturing a SynchronizationContext is a step above that, and implicitly capturing the SynchronizationContext by using await is even better.
You have to invoke the code that updates the user interface on the UI thread.
In general there are several options to do that:
calling Invoke on a Control
using a BackgroundWorker that has been started on the UI thread
calling Post on the SynchronizationContext of the UI thread
using Task.ContinueWith with the TaskScheduler of the UI thread
using asynchronous calls with async/await
In my opinion last method is by far the easiest for the developer, but it is only available with C# 5 and .NET 4.5 or .NET 4.0 with the Microsoft.Bcl.Async package. Tasks are nearly as easy to use but both of these methods would require you to change your code. They won't work to simply invoke a method on the UI thread from a thread pool thread.
The BackgroundWorker is usually used to schedule an action that takes quite some time. Its ReportProgress method raises the ProgressChanged event on the thread that called the RunWorkerAsync method. As such it is also not a good solution to your problem.
SynchronizationContext.Post and Control.Invoke work similarly, but Control.Invoke doesn't require you to capture the UI context, so it's easier to use.
To summarize it you should use Control.Invoke unless you want to change your code to make use of async/await.
It's fine as long as the UI thread isn't overburdened by those invokes. It does introduce some latency to the communication, which usually isn't an issue, however, it can become more of a problem if you're doing a lot of Invokes, or if the UI thread is doing a lot of work (eg. rendering complex graphs or something like that). Invoke is a synchronous method - it will not return until the invoked command is actually processed, and returns its return value.
As long as you're not tied up by these issues, all is well. Profiling and performance testing is critical to allocate your resources correctly, guessing is usually a huge waste of time and resources.
If you don't need the resulting value (or at least not synchronously) and you're starting to get into performance trouble, have a look at BeginInvoke, which handles the invoking asynchronously. This means your networking thread doesn't have to wait for the UI thread to work. This is quite critical in high performance servers with thousands of connections. They simply can't afford to wait while the UI does its thing.
However, do note, that having a server socket running on a different thread is not a good solution for larger servers, and in fact, it's no longer the easiest solution either. .NET now has great support for asynchronous calls and callbacks, making implementations of asynchronous processing a breeze. In your typical Winforms application, it means that I/O blocking applications can work without having constantly running and polling threads. For example, waiting for a new connection can be as simple as:
var connection = await listener.AcceptTcpClientAsync();
That's it. Automagically, all the callbacks will be processed at the right time, without blocking the processing, all of your own code always running on the main UI thread. In other words, you can easily do this:
while (!aborted)
{
var connection = await listener.AcceptTcpClientAsync();
tbxLog.Text += "New connection!\r\n";
}
While this seems like an infinite loop blocking the UI thread indefinitely, the reality is that when the application gets to the await keyword, it will register an asynchronous callback and returns. Only when the asynchronous callback is actually invoked (by IOCP in this case) is the code resumed (on the UI thread), and tbxLog has the text appended, followed by waiting for another connection.
I've never had problems doing it this way. No matter how you set it up, updating your controls has to be done on the thread they were created on. If you use a BackgroundWorker or some other async construct, somewhere an invoke is going to be called. I typically create a method on the form like:
delegate void TextSetter(string text);
internal void SetText(string text)
{
//call on main thread if necessary
if (InvokeRequired)
{
this.Invoke((TextSetter)SetText, text);
return;
}
//set the text on your label or whatever
this.StatusLabel.Text = text;
}
I've used that method in a number of applications and it's never been a problem, even updating many times per second.
As far as I'm aware, the only way to get around calling an invoke is to have your main thread constantly poll for updates, which is generally accepted as a really bad way to do things.
A really obvious simplification is to abstract away the InvokeRequired/Invoke into an extension method for a Control.
public static class FormExt {
public static void Execute(this Control c, Action a) {
if (c.InvokeRequired) {
c.Invoke(a);
} else {
a();
}
}
}
Now you just wrap up normal form updates into a lambda and execute them.
form1.Execute(() => form1.Text = "Hello world");
I am writing a library, and would like to be able to fire a callback on a specified thread, so the end-user does not have to worry about thread-safety.
I tried using ExecutionContext, but that didn't work out too well, it would fire in the specified context (a new thread), but not on the thread that originally called the function.
The code should work like this:
void Connect() {
// This should be in the same thread ..
SocketAsyncEventArgs.Completed += eventHandler;
Socket.ConnectAsync(SocketAsyncEventArgs)
}
void eventHandler() {
// .. as this
}
You can't just run your code on some existing thread. That thread is already executing other code. But, it can provide you some way to run your code on it. The main thread in a WPF application does this using Dispatcher.Invoke(). The main thread of a WinForms application uses Control.Invoke().
There is a more general way to do this: use Synchronization.Context.Current. This would work for the main thread of WPF or WinForms application, but would execute the callback on a thread pool thread otherwise. (Unless there is some sort of custom synchronization context, which I think is very rare.)
But this is the best you can do. Like I said, you can't run your code on some other thread when you want. The code in that other thread has to allow you to do that.
That's the thing about asynchronous functions -- you can't guarantee when you'll get called back, or what thread will be running your callback function. Consider that the cost of being able to "set it and forget it".
There's usually no need for that much control anyway. If you "need" to have a specific thread run your callback, what you really need is to review why that's necessary. If it's something that needs to run on the UI thread, there's Control.Invoke. (The UI thread anticipates needing to be handed stuff to do, because of how the architecture works, so controls have a way to pass callbacks to run on that thread. You can't just up and do that with arbitrary threads -- they have to be expecting to be passed a callback like that.) Otherwise, if you have an issue with locks or something, chances are you're trying to use asynchronous functionality to do stuff that should really be done synchronously in a separate thread.
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 have a situation in which I want a thread to process some sequential logic. This thread would need to interact with the main thread on occasion in order to update user input. But it should continue running otherwise without bothering the main thread. I am hopping to do this in an event-driven manner, so that the main thread doesn't have to pole the other thread for interrupts. What is the best way to do this? Is there an event-driven technique to communicating between threads much like there is in MFC?
I am using Visual Studio 2008 and (obviously) the .Net 3.5 framework.
Use the BackgroundWorker component.
Here you can find the best and complete tutorial about threading in C#, with code samples and examples.
AutoResetEvent and ManualResetEvent might be what you are after. Basically your main thread would wait using the various Wait methods of these classes until you signal from your other thread using the Set method. Then your wating thread will resume and continue with whatever comes afer Wait.
This is as good as it gets for an event-style. You have to wait and listen to receive an react on an event. How else are you supposed to stop your thread work in case you get an event gracefully? This is not possible with threads in general in any language.
Your only other possibility is frequent interrupting and polling.
Have a look at .Net Reactive Extensions IObservable and in particular the SubscribeOn and ObserveOn extension methods.
ObserveOn is where the work is done ( your background thread ), SubscribeOn is where the notifications go ( your UI thread ).
If you are using the BackgroundWorker you can raise a Progress event.
Here's an example on how to update a progress bar.
Ah ha! there is an event-driven way to do it. I borrowed the Dispatcher from WPF. I just give the spinning thread access to the main thread's CurrentDispatcher I let the thread spin and when it needs attention it invokes a delegate on the Dispatcher and sleeps waiting for the main thread to interrupt it. I know I could use Invoke instead of BeginInvoke, but I needed to use the interrupt because the method that restarts the worker thread is not a synchronous part of the dispatched delegates stack.
For better or worse, here is my code:
private void Run()
{
while (true)
{
...
// Need attention from the main thread
// "_main" is the main thread's Dispatcher instance.
_main.BeginInvoke(new MyEventHandler(OnNeedsAttention), this, new MyEventArgs(...));
try
{
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException) { }
}
}