通过BackgroundWorker的启动停止线程 [英] Stopping Thread started by backgroundworker

查看:165
本文介绍了通过BackgroundWorker的启动停止线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个采用一个BackgroundWorker Windows窗体。 BackgroundWorker的实例化对象,然后执行该对象的方法。我的问题是,当我使用backgroundworker.CancelAsync远程对象上运行的方法不会停止。在下面的例子中,DoWork的方法继续按钮取消被点击后执行。仅供参考,DoWork的是循环直通电子表格,做基于电子表格中的行一些数据操作。

I have a windows form which utilizes a backgroundworker. The backgroundworker instantiates an object and then executes a method in that object. My problem is that when I use backgroundworker.CancelAsync the method running on the remote object does not stop. In the example below, the dowork method continues to execute after button cancel is clicked. FYI, dowork is looping thru a spreadsheet and doing some data manipulation based on the rows in the spreadsheet.

    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();
    }



思考?

Thoughts?

感谢

推荐答案

btnCancel_Click 你必须通过取消请求您工人对象;否则,它永远不会被通知。在 BackgroundWorker.CancelAsync()什么都不做只是简单地设置了 BackgroundWorker.CancellationPending 属性,通知的的。BackgroundWorker的的(用户界面,而不是执行任务),您的任务已被取消的消费者

In btnCancel_Click you must pass the cancellation request to your worker object; otherwise, it will never be notified. The BackgroundWorker.CancelAsync() does not do anything just simply sets the BackgroundWorker.CancellationPending property, notifying the consumer of the BackgroundWorker (the UI, not the executed task) that your task has been cancelled.

所以,你需要什么:

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();
   }
}

和你应该如何实现通知:

And how should you implement the notification:

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 && ...)
        {
            // ...
        }
    }
}

这篇关于通过BackgroundWorker的启动停止线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆