停止线程由backgroundworker启动

我有一个使用背景工作者的窗体。 backgroundworker实例化一个对象,然后在该对象中执行一个方法。 我的问题是,当我使用backgroundworker.CancelAsync时,在远程对象上运行的方法不会停止。 在下面的示例中,单击按钮取消后,dowork方法继续执行。 仅供参考,dowork通过电子表格循环并根据电子表格中的行进行一些数据操作。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { myObject newObject = new myObject(); newObject.dowork(); if (backgroundWorker1.CancellationPending) { e.Cancel = true; backgroundWorker1.ReportProgress(0); return; } } private void btnCancel_Click(object sender, EventArgs e) { if (backgroundWorker1.IsBusy) backgroundWorker1.CancelAsync(); } 

思考?

谢谢

btnCancel_Click您必须将取消请求传递给您的工作者对象; 否则,它将永远不会被通知。 BackgroundWorker.CancelAsync()不做任何事情只是简单地设置BackgroundWorker.CancellationPending属性,通知消费者BackgroundWorker (UI,而不是执行的任务)您的任务已被取消。

那么你需要什么:

 MyObject myObject; // This method is executed on the worker thread. Do not access your controls // in the main thread from here directly. private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { myObject = new MyObject(); // The following line is a blocking operation in this thread. // The user acts in the UI thread, not here, so you cannot do here // anything but wait. myObject.DoWork(); // Now DoWork is finished. Next line is needed only to notify // the caller of the event whether a cancel has happened. if (backgroundWorker1.CancellationPending) e.Cancel = true; myObject = null; } private void btnCancel_Click(object sender, EventArgs e) { if (backgroundWorker1.IsBusy) { backgroundWorker1.CancelAsync(); // You must notify your worker object as well. // Note: Now you access the worker object from the main thread! // Note2: It would be possible to pass the worker to your object // and poll the backgroundWorker1.CancellationPending from there, // but that would be a nasty pattern. BL objects should not // aware of the UI components. myObject.CancelWork(); } } 

你应该如何实现通知:

 public class MyObject { // normally you should use locks to access fields from different threads // but if you just set a bool from one thread and read it from another, // then it is enough to use a volatile field. private volatile bool isCancelRequested; // this will be called from the main thread public void CancelWork() { isCancelRequested = true; } // This method is called from the worker thread. public void DoWork() { // Make sure you poll the isCancelRequested field often enough to // react to the cancellation as soon as possible. while (!isCancelRequested && ...) { // ... } } }