MedHelen

I have a mutilthread in a windows application, like this in the main form Load

private void Form_Load(object sender, EventArgs e)

{

// Get ready to load answer asynchronously

LoadAnswersDelegate loadAnswer = new LoadAnswersDelegate(LoadAnswers);

//write answer

this.BeginInvoke(loadAnswer);

}

Then I have a next button on the form to go to another page, how can I kill this loadAnswer before I go there.

private void btnNext_Click(object sender, EventArgs e)

{

How to Kill Load answer here

}

Thanks

Helen




Re: Visual C# General Kill a thread beginInvoke

IanG

You can't. You're using an example of the .NET v1 Asynchronous Pattern here, and it doesn't support cancellation. (The v1 async pattern is the BeginXxx/EndXxx thing. Asynchronous delegate invocation is one of many examples of this.)

There's the event-based asynchronous pattern, which was introduced in .NET v2.0. This doesn't replace the v1 pattern - the two are designed for different scenarios. This newer pattern does support cancellation. The BackgroundWorker class implements this pattern, and it would be fairly straightforward to convert code that uses asynchronous delegate invocation in the manner you've shown here into code that uses the BackgroundWorker.

However, it probably won't do what you're expecting. You can call Cancel, but the code that runs on the worker thread (your LoadAnswers method) has to watch for cancellation requests. There's nothing the BackgroundWorker can do to interrupt the work in progress. All it does is provides an idiom for cancellation - your UI thread can ask to cancel an operation, and the worker thread can poll the BackgroundWorker to ask "have we been cancelled yet " If the worker never checks the cancellation status, then cancellation does nothing.

You might be wondering why the BackgroundWorker doesn't just terminate the thread. The problem with doing that is that it leaves the process in an unknown state - the only reasonable thing you can do after terminating a thread is terminate the process. (Or at least the AppDomain.) Indeed, the only reason .NET has a Thread.Abort method is because it needs to be able to terminate rogue threads when shutting down an AppDomain.

A while ago I wrote a blog entry explaining the options for cancelling worker thread operations: http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation and this also discusses why aborting the thread is a really bad idea. This article predates the BackgroundWorker, but the same techniques apply. There's a fundamental issue here: trying to stop what one thread is doing from another thread requires the target thread's co-operation if you want to be able to carry on doing useful work afterwards. If you just pull the rug out from under a thread that was in the middle of something, you've got no idea what state it left the process in. It doesn't really matter what techniques you're using to asynchronize the work - this is a fundamental issue and you'll run into it in any case. (The same issue would apply in unmanaged C++. Or in Java. Or in an embedded system. It's a fundamental problem. It requires something radical, such as using transactions for all memory access, to solve it.)

Given that, switching to BackgroundWorker probably isn't worth the effort here. Yes, it provides a cancellation mechanism, but it doesn't really do much more than provide you with a flag... You could get the same effect with a volatile boolean, and carry on using your existing async delegate invocation.





Re: Visual C# General Kill a thread beginInvoke

MedHelen

Thanks for your reply. So now instead of killing the thread, I use the following:

loadAnswer is a global variable on the mail form now.

private void btnNext_click(...)

{

loadAnswer = new LoadAnswersDelegate(LoadAnswers);

this.BeginInvoke(loadAnswer);

}

to go to next page, it looks work well, except user can see the previous's half work, but those half work was disabled so it won't affect their new page work.

Do you think is there any side affect of this

Actually, I just found out that when people click next and click previous again, then the data is duplicate. So I need to delete or dispose "loadAnswer", I could not find a way to do that.

Thanks again!