BACKGROUND:
I have a class with multiple operations that take more than a couple of seconds to finish. In the meantime I want to update the UI. So normally the BackgroundWorker is the way to go. But for some reason the BackGroundWorker doesn't always work the way I want (example: when I try to use a WebBrowser with events and call the ReportProgress event the BackgroundWorker seemingly crashes).
So I avoid all of this by seperating the Ui from the main thread.
This pseudocode explains it better:
public Ui ui;
main
{
Thread threadUi = new Thread(initiateUi);
//Initiate and start Thread
//Everything I will do from here on will not have any consequences
//on my ui.
//
//Object Ui can still be publicly accessed, making it possible to
//update the user interface.
}
Now when I have an instance of class Bar I would make it accessible for the UI like this:
public Bar bar1;
public Bar bar2;
main
{
//
//other stuff here
//
Thread threadBar1 = //New Thread where I call the Bar initializer function
//and pass bar1 as parameter.
Thread threadBar2 = //idem dito, except with bar2 as parameter
//
//other stuff here
//
}
With this design I can call bar1 and bar2 from my user-interface with the following function:
Program.bar1.someFunction();
PROBLEM:
Now let's say I have a class called FooHandler. This class has a function that searches for all instances of Foo in a certain FooDepository and other functions to manipulate a Foo-object. This is a static class, because in my case, it doesn't need to have multiple instances.
But if I were to call a function from FooHandler, the function runs in my UI-thread, because that is the calling thread (I am not really sure but I couldn't find any documentation about this subject). So there is a good chance I am about to face the problem I started with.
QUESTION:
Is it possible to access the function of a static class without using processing power from the calling thread?
First of all: method scope (where it is defined) has NOTHING to do with program flow. Where method is defined (FooHandler, BarProvider or ThreadX) does not affect where it is called. Actually method is always called in caller's thread.
Because you didn't mention any models, views nor view models and in title says "c#" I'm assuming you talking about WinForms.
In WinForms UI controls needs to be called (updated) from the thread which was used to create them (usually main thread). All the UI controls implement ISynchronizeInvoke interface which is meant to do that. So, instead of regular:
progress.Position = 7;
you need to call Invoke:
progress.Invoke(new Action(() => progress.Position = 7), null)
as there is a lot of boiler-plate code I wrote a little extension function for myself:
public static class ControlExtensions
{
public static void Synchronize(this Control control, Action action)
{
if (control == null || !control.InvokeRequired)
{
action();
}
else
{
control.Invoke(action, null);
}
}
}
So now you can just:
progress.Synchronize(() => progress.Position = 7);
(a little bit less typing and easier to read)
Technically, Invoke on ISynchronizeTarget does not really call given action. It just puts a message (good old WM_xxxx) in message queue (but does this in caller's thread) with delegate as argument. Then, if target (control's) thread is processing messages (in its own thread) it gets this WM_xxxx message, calls the delegate (in callers thread - but this time it is UI thread) and returns.
If you need new Thread to call FooHandler, and you don't want to wait use Tasks (it's probably the easiest way):
Task.Factory.StartNew(() => FooHandler.SearchOrWhatever(...));
it won't wait (won't block the UI thread).
Despite all of this being said, don't assume it's done.
Multi-threading is hard. And all those construct which support save you typing, but the hard part is still there: dead-locks, race conditions, starving, etc.
It is possible by calling this function using another thread. If you use .NET 4 take a look at Task object, which will easily solve the issue. If you function return string for example, then you need Task<string> that will call your function. Then depending on your logic you will either block until it's finished or do something similar. If you are using .NET 4.5 then it's even easier with async/await.
Related
After reading up on how to use Invoke to be able to update GUI elements from other threads I worked a bit with it, and has ended up with following approach to handle it. I am fairly certain I have overcomplicated the solution, but I do believe it is working as intended.
The advantages I see with this approach is, that it allows multiple commands to be stored in short succession for consumption once the GUI thread is ready for it, and the order of the commands are maintained. The downside is that to me storing these temporary parameters looks inefficient (I could create a generic class to store all to hide them to a single object)
I have chosen to reuse the same Mutex for all calls, but different ones could be used as long they are paired up.
So what other patterns could I use to get the same results? (hopefully in a less convoluted approach.)
//The main form class.
public class GUIHandler
{
Mutex InvokeOnce = new Mutex(); //Mutex that ensures that temp storage only gets written to or read from
//tempData for Invoke Methodes
List<SomeObject> invokeParameter = new List<SomeObject>();
List<SomeOtherObject> anotherInvokeParameter = new List<SomeOtherObject>();
public GUIHandler()
{
//Some code to initialize the GUI
}
//Generic Reused InvokeDelegate
public delegate void InvokeDelegate();
//External Call with parameters different calls different names
private void SomeInvokeRequiredAction(SomeObject someParameter)
{
//call mutex for handle the storage and store the parameter
InvokeOnce.WaitOne();
invokeParameter.Add(someParameter);
InvokeOnce.ReleaseMutex();
this.BeginInvoke(new InvokeDelegate(SomeInvokeRequiredActionInvoke));
}
//Invoked Code with related name to its primary external call
private void SomeInvokeRequiredActionInvoke()
{
InvokeOnce.WaitOne();
//some random action on a GUI element that required the Invoke in first place
guiElement.Text = invokeParameter[0]
invokeParameter.RemoveAt(0);
InvokeOnce.ReleaseMutex();
}
}
If what you need is to:
Pass work to the UI thread.
Preserve order for that work.
You don't need much more than a simple Invoke. It is thread safe (so no locking is necessary). It searches for the topmost control and it's window handle and queues up work to run on it (message loop). And because it's only a single thread the work will be done in order.
As in the question that was suggested in comments, a simple solution like this one is probably enough:
Usage:
button.InvokeIfRequired(() =>
{
// This will run under the UI thread.
button.Text = "hamster";
});
Implementation:
public static void InvokeIfRequired(this ISynchronizeInvoke control, MethodInvoker action)
{
if (control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
I've found what looks like a very simple solution to my current situation.
My current situation is that I want to do some I/O-heavy operations on a new Thread, so that I do not bog down my GUI Thread. I have a function written, as a member of my Form, that does these I/O operations already, but running it on the GUI Thread really makes the application a pain to use. So my plan was to just run this function in a new Thread. So, I created a Thread variable, in my form, and am trying to get it to use that function as the ThreadStart parameter. It does not seem to like it, though.
I found an elegant looking solution, as a response to another thread, here.
///...blah blah updating files
string newText = "abc"; // running on worker thread
this.Invoke((MethodInvoker)delegate {
someLabel.Text = newText; // runs on UI thread
});
///...blah blah more updating files
From the looks of that response, I could run this function in a new Thread and then use an anonymous function to update my Form when the Thread has finished its calculations. I'm just not good enough to fill in the blanks from that response, though.
Everything I seem to read about Threads says that my ThreadStart function needs to be a static method in a new class. That response seems to suggest that I can do it within my Form class though, so that the this reference still references my Form instance. Otherwise, if my ThreadStart parameter were a different class, I'd have to pass in references to the Form instance, and that seems like more code, right?
Would anybody mind helping me fill in the context for that response? Thanks in advance!
There are a lot of ways you can do this. A very simple, straightforward one that's been around for a number of versions is to use the BackgroundWorker. It is designed for exactly this case. It has a DoWork method that runs in a background thread, and a Completed event that is fired after the work is done which runs in the UI thread (so you don't need to call invoke or anything to update the UI with the results). It even has support built in for reporting progress (the report progress event also runs in the UI thread) so you can easily update a progress bar or status text.
MSDN has some examples as well, and you can find lots more through some simple searches.
Another option, made available through C# 4.0, is to use Tasks. You can start a new task which will be run in a background thread, and then you can add a continuation which will be in the UI thread.
Here is a simple example:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() => doStuffInBackground())
.ContinueWith(task => updateUI(), TaskScheduler.FromCurrentSynchronizationContext());
}
private void updateUI()
{
throw new NotImplementedException();
}
private void doStuffInBackground()
{
throw new NotImplementedException();
}
You can of course do whatever you want in the actual lambdas that I have there, or you could even remove the lambdas and put methods in there directly as long as you ensure the signatures are correct. You could also continue chaining these continuations if you wanted, allowing you to, for example, to task 1, update a label, then do task 2, update a label, etc. The main disadvantage is that it's not good at updating a progress bar frequently inside of a loop, the way a BackgroundWorker can.
My generalized question is this: how do you write asynchronous code that is still clear and easy to follow, like a synchronous solution would be?
My experience is that if you need to make some synchronous code asynchronous, using something like BackgroundWorker, you no longer have a series of easy to follow program statements that express your overall intent and order of activities, you end up instead with a bunch of "Done" Event Handlers, each of which starts the next BackgroundWorker, producing code that's really hard to follow.
I know that's not very clear; something more concrete:
Let's say a function in my WinForms application needs to start up some amazon EC2 instances, wait for them to become running, and then wait for them to all accept an SSH connection. A synchronous solution in pseudo code might look like this:
instances StartNewInstances() {
instances = StartInstances()
WaitForInstancesToBecomeRunning(instances)
WaitForInstancesToAcceptSSHConnection(instances).
return (instances)
}
That's nice. What is happening is very clear, and the order of program actions is very clear. No white noise to distract you from understanding the code and the flow. I'd really like to end up with code that looks like that.
But in reality, I can't have a synchronous solution .. each of those functions can run for a long time, and each needs to do things like: update the ui, monitor for time-outs being exceeded, and retry operations periodically until success or time-out. In short, each of these needs to be happening in the background so the foreground UI thread can continue on.
But if I use solutions like BackgroundWorker, it seems like I don't end up with nice easy to follow program logic like the above. Instead I might start a background worker from my UI thread to perform the first function, and then my ui thread goes back to the UI while the worker thread runs. When it finishes, its "done" event handler might start the next Background Worker. WHen it finishes, its "done" event handler might start the last BackgroundWorker, and so on. Meaning you have to "follow the trail" of the Done Event handlers in order to understand the overall program flow.
There has to be a better way that a) lets my UI thread be responsive, b) let's my async operations be able to update the ui and most importantly c) be able to express my program as series of consecutive steps (as I've shown above) so that someone can understand the resultant code
Any and all input would be greatly appreciated!
Michael
My generalized question is this: how do you write asynchronous code that is still clear and easy to follow, like a synchronous solution would be?
You wait for C# 5. It won't be long now. async/await rocks. You've really described the feature in the above sentence... See the Visual Studio async homepage for tutorials, the language spec, downloads etc.
At the moment, there really isn't a terribly clean way - which is why the feature was required in the first place. Asynchronous code very naturally becomes a mess, especially when you consider error handling etc.
Your code would be expressed as:
async Task<List<Instance>> StartNewInstances() {
List<Instance> instances = await StartInstancesAsync();
await instances.ForEachAsync(x => await instance.WaitUntilRunningAsync());
await instances.ForEachAsync(x => await instance.WaitToAcceptSSHConnectionAsync());
return instances;
}
That's assuming a little bit of extra work, such as an extension method on IEnumerable<T> with the form
public static Task ForEachAsync<T>(this IEnumerable<T> source,
Func<T, Task> taskStarter)
{
// Stuff. It's not terribly tricky :(
}
On the off chance that you can't wait for 5 as Jon rightly suggests, I'd suggest that you look at the Task Parallel Library (part of .NET 4). It provides a lot of the plumbing around the "Do this asynchronously, and when it finishes do that" paradigm that you describe in the question. It also has solid support for error handling in the asynchronous tasks themselves.
Async/await is really the best way to go. However, if you don't want to do wait, you can try Continuation-passing-style, or CPS. To do this, you pass a delegate into the async method, which is called when processing is complete. In my opinion, this is cleaner than having all of the extra events.
That will change this method signature
Foo GetFoo(Bar bar)
{
return new Foo(bar);
}
To
void GetFooAsync(Bar bar, Action<Foo> callback)
{
Foo foo = new Foo(bar);
callback(foo);
}
Then to use it, you would have
Bar bar = new Bar();
GetFooAsync(bar, GetFooAsyncCallback);
....
public void GetFooAsyncCallback(Foo foo)
{
//work with foo
}
This gets a little tricky when GetFoo could throw an exception. The method I prefer is to chage the signature of GetFooAsync.
void GetFooAsync(Bar bar, Action<Func<Foo>> callback)
{
Foo foo;
try
{
foo = new Foo(bar);
}
catch(Exception ex)
{
callback(() => {throw ex;});
return;
}
callback(() => foo);
}
Your callback method will look like this
public void GetFooAsyncCallback(Func<Foo> getFoo)
{
try
{
Foo foo = getFoo();
//work with foo
}
catch(Exception ex)
{
//handle exception
}
}
Other methods involve giving the callback two parameters, the actual result and an exception.
void GetFooAsync(Bar bar, Action<Foo, Exception> callback);
This relies on the callback checking for an exception, which could allow it to be ignored. Other methods have two call backs, one for success, and one for failure.
void GetFooAsync(Bar bar, Action<Foo> callback, Action<Exception> error);
To me this makes the flow more complicated, and still allows the Exception to be ignored.
However, giving the callback a method that must be called to get the result forces the callback to deal with the Exception.
When it finishes, its "done" event handler might start the next Background Worker.
This is something that I've been struggling with for a while. Basically waiting for a process to finish without locking the UI.
Instead of using a backgroundWorker to start a backgroundWorker however, you can just do all the tasks in one backgroundWorker. Inside the backgroundWorker.DoWork function, it runs synchronously on that thread. So you can have one DoWork function that processes all 3 items.
Then you have to wait on just the one BackgroundWorker.Completed and have "cleaner" code.
So you can end up with
BackgroundWorker_DoWork
returnValue = LongFunction1
returnValue2 = LongFunction2(returnValue)
LongFunction3
BackgroundWorker_ProgressReported
Common Update UI code for any of the 3 LongFunctions
BackgroundWorker_Completed
Notify user long process is done
In some scenario (will explain later), you can wrap the async calls to a method like the following pseudo code:
byte[] ReadTheFile() {
var buf = new byte[1000000];
var signal = new AutoResetEvent(false);
proxy.BeginReadAsync(..., data => {
data.FillBuffer(buf);
signal.Set();
});
signal.WaitOne();
return buf;
}
For the above code to work, the call back needs to be invoked from a different thread. So this depends on what you are working with. From my experience, at least Silverlight web service calls are handled in UI thread, which means the above pattern cannot be used - if the UI thread is blocked, the previous begin call even cannot be carried out. If you are working with this kind of frameworks, another way to handle multiple async calls is to move your higher level logic to a background thread and use UI thread for communication. However, this approach is a little bit over killing in most cases because it requires some boilerplate code to start and stop background thread.
I've been researching on how to do this for about a week and I'm still not sure about the correct approach, in some examples I see the Thread class is used in others I see Invoke is used which has confused me a bid.
I have a GUI program in c# which contains a textBox which will be used to give information to the user.
The problem I'm facing is that I'm not sure how I can append text to textBox from another class which is running on another thread. If someone can show me a working example, it would help me greatly.
Best Regards!
Easy:
MainWindow.myInstance.Dispatcher.BeginInvoke(new Action(delegate() {MainWindow.myInstance.myTextBox.Text = "some text";});
WHERE MainWindow.myInstance is a public static variable set to the an instance of MainWindow (should be set in the constructor and will be null until an instance is constructed).
Ok thats a lot in one line let me go over it:
When you want to update a UI control you, as you say, have to do it from the UI thread. There is built in way to pass a delegate (a method) to the UI thread: the Dispatcher. I used MainWindow.myInstance which (as all UI components) contains reference to the Dispatcher - you could alternatively save a reference to the Dispatcher in your own variable:
Dispatcher uiDispatcher = MainWindow.myInstance.Dispatcher;
Once you have the Dispatcher you can either Invoke() of BeginInvoke() passing a delegate to be run on the UI thread. The only difference is Invoke() will only return once the delegate has been run (i.e. in your case the TextBox's Text has been set) whereas BeginInvoke() will return immediately so your other thread you are calling from can continue (the Dispatcher will run your delegate soon as it can which will probably be straight away anyway).
I passed an anonymous delegate above:
delegate() {myTextBox.Text = "some text";}
The bit between the {} is the method block. This is called anonymous because only one is created and it doesnt have a name - but I could instantiated a delegate:
Action myDelegate = new Action(UpdateTextMethod);
void UpdateTextMethod()
{
myTextBox.Text = "new text";
}
Then passed that:
uiDispatcher.Invoke(myDelegate);
I also used the Action class which is a built in delegate but you could have created your own - you can read up more about delegates on MSDN as this is going a bit off topic..
Sounds like you're using a background thread for processing, but want to keep the UI responsive? The BackgroundWorker sounds like the ticket:
The BackgroundWorker class allows you
to run an operation on a separate,
dedicated thread. Time-consuming
operations like downloads and database
transactions can cause your user
interface (UI) to seem as though it
has stopped responding while they are
running. When you want a responsive UI
and you are faced with long delays
associated with such operations, the
BackgroundWorker class provides a
convenient solution.
Just use BackgroundWorker for the same. It is simple and takes away the pain of managing threads of your own. for more, you can see: http://dotnetperls.com/backgroundworker
While going through this article I came across this statement -
If you are writing your own WPF
objects, such as controls, all methods
you use should call VerifyAccess
before they perform any work. This
guarantees that your objects are only
used on the UI thread, like this
//Using VerifyAccess and CheckAccess
public class MyWpfObject : DispatcherObject
{
public void DoSomething()
{
VerifyAccess();
// Do some work
}
public void DoSomethingElse()
{
if (CheckAccess())
{
// Something, only if called
// on the right thread
}
}
}
I haven't seen this in any of the custom controls I have come across(as far as I remember).
Do you use this while building custom controls?
Is it must to do this or just nice to have?
Anyone ever faced any issue due to absence of this in your controls?
Nah, never used this. And never noticed somebody use it in the context of Custom Controls. This rule is not followed in WPF Toolkit too.
This approach not only pollutes the code but also makes your custom control responsible for something it shouldn't care about. Consider situation where you always doing:
// Don't do this in all methods of your custom control!
public void Foo()
{
if (!CheckAccess())
{
Dispatcher.Invoke(()=> Foo()); // Transit to UI Thread
return;
}
// .. do work in UI.
}
At first glance this code looks fine. If you are not in UI thread, transit to UI thread, perform operation and return result. Right? - WRONG!
Problem 1. When you call Dispatcher.Invoke() you block calling thread until your request is processed by UI thread. This leads to poor performance. Of course, you can change this to Dispatcher.BeginInvoke() now your clients should be aware that their operation is done asynchronously. I.e. if client writes something to control, and then immediately reads it back there is no guarantee, that the operation already executed by UI thread.
Problem 2. Consider subsequent calls to the method Foo() from non UI thread. For example it's called in cycle:
// Somewhere not in UI
for (int i = 0; i < 1000000; i++)
{
control.Foo(); // Looks good, but performance is awful!
}
Instead of blocking calling thread 1000000 times, developer could implement one check in the calling thread and transit to UI when necessary, instead of unconsciously jumping back and worth between threads.
Furthermore WPF will make this check for you when you access UI element from non-UI thread. It screams loud enough to crush application and be heard by developer who has done something wrong :).
Hope this helps.