I am writing a Visual C# program that executes a continuous loop of operations on a secondary thread. Occasionally when that thread finishes a task I want it to trigger an eventhandler. My program does that but the when the event handler is triggered, the secondary thread waits until the event handler is finished before continuing the thread. How do I make it continue? Here is the way I currently have it structured...
class TestClass
{
private Thread SecondaryThread;
public event EventHandler OperationFinished;
public void StartMethod()
{
...
SecondaryThread.Start(); //start the secondary thread
}
private void SecondaryThreadMethod()
{
...
OperationFinished(null, new EventArgs());
... //This is where the program waits for whatever operations take
//place when OperationFinished is triggered.
}
}
This code is part of an API for one of my devices. When the OperationFinished event is triggered I want the client application to be able to do whatever it needs to (i.e. update the GUI accordingly) without haulting the API operation.
Also, if I do not want to pass any parameters to the event handler is my syntax correct by using OperationFinished(null, new EventArgs())
?
With the Task Parallel Library it is now possible to do the following:
So you want to raise the event in a manner that prevents the listeners from blocking the background thread? Gimme a couple minutes to whip up an example; it's pretty simple :-)
Here we go: first an important note! Whenever you call
BeginInvoke
you must call the correspondingEndInvoke
, otherwise if the invoked method threw an exception or returned a value then the ThreadPool thread will never be released back to the pool, resulting in a thread-leak!Look at the BackgroundWorker class. I think it does exactly what you are asking for.
EDIT: What I think you are asking is how to fire an event when only a small part of the overall background task is complete. BackgroundWorker provides an event called "ProgressChanged" that allows you to report back to the main thread that some portion of the overall process is complete. Then, when all of the async work is complete, it raises the "RunWorkerCompleted" event.
Try the BeginInvoke and EndInvoke methods on the event delegate - these return immediately, and allow you to use polling, a wait handle or a callback function to notify you when the method has completed. See here for an overview; in your example, the event is the delegate you'll be using
Maybe Method2 or Method3 below can help :)
}
No. Typically, you would call it as:
You should always pass an object as a sender - it's expected in the pattern (although typically ignored). EventArgs.Empty is better than new EventArgs(), as well.
In order to fire this in a separate thread, the easiest option is probably to just use the thread pool:
That being said, raising an event on a separate thread is something that should be thoroughly documented, as it will potentially cause unexpected behavior.