Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
277 views
in Technique[技术] by (71.8m points)

c# - Notify when thread is complete, without locking calling 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...