I am having a function where I have used a thread in c#.net.
I am having a another function on the next line of that thread. But this function has to be called only after the thread gets executed.
How can i do it ?
Example..
Somefunction()
{
// thread //(thread started)
add() (another function but need to be executed only tha above thread gets over)
}
Use a BackgroundWorker and include the function call in the worker completeted event handler.
var worker = new BackgroundWorker();
_worker.DoWork += delegate { DoStuff(); };
_worker.RunWorkerCompleted += worker_RunWorkerCompleted;
_worker.RunWorkerAsync();
[...]
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
/// Do post-thread stuff
}
Use Thread.Join to block the current thread until the specified thread has finished execution.
Why start a separate thread if you want execution to be single threaded?
by "after the thread gets executed", do you mean it must have started? or it must have finished?
If you mean finished, then you would typically Join() the thread - but there is no point Join()ing a thread you have stared in the line before (just execute the code directly). The other approach is to use a "callback" at the end of the threaded method.
If you mean started, then you can do things like:
object lockObj = new object();
lock(lockObj) {
ThreadPool.QueueUserWorkItem(delegate {
lock(lockObj) {
Monitor.Pulse(lockObj);
}
// do things (we're on the second thread...)
});
Monitor.Wait(lockObj);
}
// thread has definitely started here
You can use , for instance, a ManualResetEvent.
When you start the processing on the other thread, you call the reset method.
When processing on the other thread has finished, you call set.
Then, the method that must be executed on the 'main thread', needs to wait until the ManualResetEvent has been set before it can execute.
For more info, you can have a look at the ManualResetEvent at MSDN.
If add() is thread safe, just call it at the end of the function you pass to create thread.
You could try the following, it may not work for your scenario: I can't tell given the amount of detail you provided:
First create a delegate:
public delegate int MyThreadSignature(Something arg);
Then use the Begin/End Invoke pattern:
var thread = new MyThreadSignature(WorkerMethod);
thread.BeginInvoke(theArg,
MyThreadEnded, /*Method to call when done*/,
thread /*AsyncState*/);
Create the MyThreadEnded method:
void MyThreadEnded(IAsyncResult result)
{
var thread = (MyThreadSignature)result.AsyncState;
var result = thread.EndInvoke(result);
// Call your next worker here.
}
The method to call MUST have the signature in the example: Name(IAsyncResult result).
Related
I have a method:
public void Run()
{
instalProgressPageViewModel.ExecuteButton_Click();
//waiting here
Environment.Exit(0);
}
Method Execute_Click() calls a installers of msi packages. Those installers run in separate threads:
this.uiDispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
new InstallationCompleted(this.completeInstallDelegate),
installationState);
where:
this.completeInstallDelegate // method which should be called after the thread is done.
Waiting for function CompleteInstall is crucial as its finalize installation and begins installation next msi package in a list of packages.
In the sample code of method Run app is closed before anything can happen.
I tried putting:
while(true){}
In a place of // waiting here and put breakpoint in CompleteInstall method to check if it will be called but it wasn't hit. App is stucked in infite loop inside while.
What can I do to force my main thread to wait for threads and jump into completeinstall method when its called by delegate?
#Update:
With your suggestions my code looks like this:
there is
public static ManualResetEvent mre // global object initialized in main
and other class is:
public void Run()
{
instalProgressPageViewModel.ExecuteButton_Click();
mre.WaitOne();
Environment.Exit(0);
}
ExecuteButton_Click call this function:
public void StartProcessing()
{
var processor = new Action(this.DoProcessing);
processor.BeginInvoke(null, null);
}
now DoProcessing:
private void DoProcessing()
{
var installationState = this.Execute();
// Schedule the update function in the UI thread.
this.uiDispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
new InstallationCompleted(this.completeInstallDelegate),
installationState);
}
and finally completeInstallDelegate
private void CompleteInstall(InstallationState installationState)
{
App.mre.Set();
/*
Some code
*/
this.PostInstallAndNext();
}
If I put break Point at the line App.mre.Set() it is never hit.
and for unknow reason for me the DoProcessing is called after mre.WaitOne(). Does Action and BeginInvoke work out of sync too?
Thanks for updating the question.
It looks like you are never creating an actual new Thread, i.e. you are suspending the main thread and effectively deadlocking your application.
You could create an new Thread here:
public void StartProcessing()
{
var thread = new Thread(() => this.DoProcessing);
thread.Start();
}
You could use the ManualResetEvent class.
Create a ManualResetEvet
ManualResetEvent mre = new ManualResetEvent(false);
In the Main method wait for this event to get signalled.
mre.WaitOne();
In your delegate (when the work is finished), signal the event.
mre.Set();
A simple solution would be to use ManualResetEvent.
You would then have a blocking call to WaitOne, until you call Set from the other thread.
I am working on a legacy application that is built on top of NET 3.5. This is a constraint that I can't change.
I need to execute a second thread to run a long running task without locking the UI. When the thread is complete, somehow I need to execute a Callback.
Right now I tried this pseudo-code:
Thread _thread = new Thread(myLongRunningTask) { IsBackground = True };
_tread.Start();
// wait until it's done
_thread.Join();
// execute finalizer
The second option, which does not lock the UI, is the following:
Thread _thread = new Thread(myLongRunningTask) { IsBackground = True };
_tread.Start();
// wait until it's done
while(_thread.IsAlive)
{
Application.DoEvents();
Thread.Sleep(100);
}
// execute finalizer
Of course the second solution is not good cause it overcharge the UI.
What is the correct way to execute a callback when a _thread is complete? Also, how do I know if the thread was cancelled or aborted?
*Note: * I can't use the BackgroundWorker and I can't use the Async library, I need to work with the native thread class.
There are two slightly different kinds of requirement here:
Execute a callback once the long-running task has completed
Execute a callback once the thread in which the long-running task was running has completed.
If you're happy with the first of these, the simplest approach is to create a compound task of "the original long-running task, and the callback", basically. You can even do this just using the way that multicast delegates work:
ThreadStart starter = myLongRunningTask;
starter += () => {
// Do what you want in the callback
};
Thread thread = new Thread(starter) { IsBackground = true };
thread.Start();
That's very vanilla, and the callback won't be fired if the thread is aborted or throws an exception. You could wrap it up in a class with either multiple callbacks, or a callback which specifies the status (aborted, threw an exception etc) and handles that by wrapping the original delegate, calling it in a method with a try/catch block and executing the callback appropriately.
Unless you take any special action, the callback will be executed in the background thread, so you'll need to use Control.BeginInvoke (or whatever) to marshal back to the UI thread.
I absolutely understand your requirements, but you've missed one crucial thing: do you really need to wait for the end of that thread synchronously? Or maybe you just need to execute the "finalizer" after thread's end is detected?
In the latter case, simply wrap the call to myLongRunningTask into another method:
void surrogateThreadRoutine() {
// try{ ..
mytask();
// finally { ..
..all 'finalization'.. or i.e. raising some Event that you'll handle elsewhere
}
and use it as the thread's routine. That way, you'll know that the finalization will occur at the thread's and, just after the end of the actual job.
However, of course, if you're with some UI or other schedulers, the "finalization" will now run on yours thread, not on the "normal threads" of your UI or comms framework. You will need to ensure that all resources are external to your thread-task are properly guarded or synchronized, or else you'll probably clash with other application threads.
For instance, in WinForms, before you touch any UI things from the finalizer, you will need the Control.InvokeRequired (surely=true) and Control.BeginInvoke/Invoke to bounce the context back to the UI thread.
For instance, in WPF, before you touch any UI things from the finalizer, you will need the Dispatcher.BeginInvoke..
Or, if the clash could occur with any threads you control, simple proper lock() could be enough. etc.
You can use a combination of custom event and the use of BeginInvoke:
public event EventHandler MyLongRunningTaskEvent;
private void StartMyLongRunningTask() {
MyLongRunningTaskEvent += myLongRunningTaskIsDone;
Thread _thread = new Thread(myLongRunningTask) { IsBackground = true };
_thread.Start();
label.Text = "Running...";
}
private void myLongRunningTaskIsDone(object sender, EventArgs arg)
{
label.Text = "Done!";
}
private void myLongRunningTask()
{
try
{
// Do my long task...
}
finally
{
this.BeginInvoke(Foo, this, EventArgs.Empty);
}
}
I checked, it's work under .NET 3.5
You could use the Observer Pattern, take a look here:
http://www.dofactory.com/Patterns/PatternObserver.aspx
The observer pattern will allow you, to notify other objects which were previously defined as observer.
A very simple thread of execution with completion callback
This does not need to run in a mono behavior and is simply used for convenience
using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
public class ThreadTest : MonoBehaviour
{
private List<int> numbers = null;
private void Start()
{
Debug.Log("1. Call thread task");
StartMyLongRunningTask();
Debug.Log("2. Do something else");
}
private void StartMyLongRunningTask()
{
numbers = new List<int>();
ThreadStart starter = myLongRunningTask;
starter += () =>
{
myLongRunningTaskDone();
};
Thread _thread = new Thread(starter) { IsBackground = true };
_thread.Start();
}
private void myLongRunningTaskDone()
{
Debug.Log("3. Task callback result");
foreach (int num in numbers)
Debug.Log(num);
}
private void myLongRunningTask()
{
for (int i = 0; i < 10; i++)
{
numbers.Add(i);
Thread.Sleep(1000);
}
}
}
Try to use ManualRestEvent to signal of thread complete.
Maybe using conditional variables and mutex, or some functions like wait(), signal(), maybe timed wait() to not block main thread infinitely.
In C# this will be:
void Notify()
{
lock (syncPrimitive)
{
Monitor.Pulse(syncPrimitive);
}
}
void RunLoop()
{
for (;;)
{
// do work here...
lock (syncPrimitive)
{
Monitor.Wait(syncPrimitive);
}
}
}
more on that here:
Condition Variables C#/.NET
It is the concept of Monitor object in C#, you also have version that enables to set timeout
public static bool Wait(
object obj,
TimeSpan timeout
)
more on that here:
https://msdn.microsoft.com/en-us/library/system.threading.monitor_methods(v=vs.110).aspx
I have time-consuming function and I want to give the user an opportunity to stop it by clicking a button in the UI when he notices that it takes too long. How can I do this?
You can use BackgroundWorker class to run time and resource consuming stuff on other thread, and use its CancelAsync method, to request (it's not immediate execution) cancelation of the other thread.
For concrete example on how to implement that, can have a look on accepted answer in this question:
How to wait for a BackgroundWorker to cancel?
First of all, you need to run the time-consuming function in a thread separate from the main thread. Otherwise the UI will stop responding.
Then you need to have a static variable or a shared instance where the UI can set a flag indicating that the time-consuming function should stop.
Finally, the time-consuming function should regular check the flag and stop processing if it is set.
The BackgroundWorker class implements this pattern and solves a few other requirements as well (such as the inter-thread communication and the progress reporting).
Lets say your time-consuming method is called MyTimeConsumingMethod.
void MyTimeConsumingMethod()
{
//Do stuff
}
Put globally a thread:
Thread t;
Put in your Form_Load()
t = new Thread(new ThreadStart(MyTimeConsumingMethod));
t.Start();
And on button press:
t.Abort();
Try running it on a Background Worker.
This Gives a good example of how to use it.
Then you can call
Worker.CancelAsync();
when the user wants to cancel the operation
Here's an example
bool _cancel = false;
private void count()
{
_cancel = false;
new System.Threading.Thread(delegate()
{
for (int i = 0; i < 100000; i++)
{
if (_cancel)
break;
Console.WriteLine(i);
}
}).Start();
}
private void button1_Click(object sender, EventArgs e)
{
_cancel = true;
}
I have a c# .NET winforms app making this async call:
simpleDelegate.BeginInvoke(null, null);
My function is being called by the delegate and that all works great. The problem is, after the function finishes on the worker thread, I need the main thread to update some controls on my winform. If the worker thread tries to update these controls, .NET freaks out. But I need the main thread to remain responsive to user actions, and then call my function UpdateFormAfterServerCall() ONLY AFTER the worker thread finishes calling the async function.
I would greatly appreciate if you can give me a concise code sample, rather than abstractly explain how to do this. I've read a hundred explanations already, and am just having trouble wiring it together correctly.
Note: Before the BeginInvoke I have:
simpleDelegate = new MethodInvoker(CallServer);
From different thread if you want to update GUI which is owned by another thread use MethodInvoker
if(control.InvokeRequired)
control.Invoke( (MethodInvoker) ( ()=> updating_function() ) );
else
updating_function();
You could use a BackgroundWorker:
BackgroundWorker bw = new BackgroundWorker();
string result = null;
bw.DoWork += (s, e) =>
{
// Executes on background thread.
// UI remains responsive to user activity during this time.
result = CallServer();
};
bw.RunWorkerCompleted += (s, e) =>
{
// Executes on UI thread upon completion.
resultTextBox.Text = result;
};
bw.RunWorkerAsync();
The Control class (Form is a Control as well) has an Invoke method, you can call this from any thread to execute code on the GUI thread.
In addition, Control has a convenient InvokeRequired property that informs you whether you are on the GUI thread already. You could for instance create the following method in your form:
public class MyForm
{
// ...
public void UpdateMe()
{
if (InvokeRequired)
{
Invoke(new Action(UpdateMe));
return;
}
// Code to update the control, guaranteed to be on the GUI thread
}
}
Here is the code sample [what you want exactly] -
http://www.yoda.arachsys.com/csharp/threads/winforms.shtml
& you can read about all flavours of async here -
http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.100).aspx
I tried the following (pseudocode) but I always get a deadlock when Iam trying to stop my thread.
The problem is that Join() waits for the thread to complete and a pending Invoke() operation is also waiting to complete. How can I solve this?
Thread workerThread = new Thread(BackupThreadRunner);
volatile bool cancel;
// this is the thread worker routine
void BackupThreadRunner()
{
while (!cancel)
{
DoStuff();
ReportProgress();
}
}
// main thread
void ReportProgress()
{
if (InvokeRequired)
{
Invoke(ReportProgress);
}
UpdateStatusBarAndStuff();
}
// main thread
void DoCancel()
{
cancel=true;
workerThread.Join();
}
You could use BeginInvoke(ReportProgress) - that way your worker thread doesn't have to wait for the UpdateStatusBarAndStuff method to finish.
use `BeginInvoke' instead
I would do it a slightly different way:
private Thread workerThread;
void StartButtonClick()
{
workerThread = new Thread(ReportProgress);
thread.Start();
}
void CancelButtonClick()
{
// If you use a while(bool), it will repeat the task forever
// or with no while and just a bool, you'll have to check the value of the bool in each line
// so simply aborting it (providing you clean up) is accceptable.
workerThread.Abort();
// If you don't mind your user waiting:
// workerThread.Join(1000);
}
void ReportProgress()
{
if (InvokeRequired)
{
Invoke(ReportProgress);
return;
}
UpdateStatusBarAndStuff();
}
The best practice advice is "don't abort". This is based on the fact you don't know at what point the abort call will exit your code - it could be half way through creating a Stream. So you end up with a choice: can you guarantee that at whatever line the code exits, it will be in a reasonable state to do so?
If you can't then you will need to use a Thread.Join().
Even with a Thread.Join, the user may get bored and quit (ALT+F4) the app, and you have exactly the same situation as you had with the Thread.Abort() call.