BackgroundWorker不会在CancelAsync()上停止并且只能运行一次

时间:2015-10-17 20:01:07

标签: c# winforms progress-bar backgroundworker

我有一个名为Sorter的表单。它上面有一个“jademy”按钮,可打开“进度窗口”窗口

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="mw.mobilepccommunication" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

“进度窗口”代码表格如下:

private void jademy_Click(object sender, EventArgs e)
{
    ProgressWindow progress = new ProgressWindow();
    progress.ShowDialog();
}

现在。我有三个问题。

  1. 点击停止按钮不执行任何操作。似乎'backgroundWorker.CancelAsync()'不会停止该过程。

  2. 当我关闭进度窗口并且我想再次运行它时,我必须等待一段时间再点击'jademy'按钮。否则,进度窗口显示如下: enter image description here(并没有任何变化)而不是:enter image description here看起来程序“记住”工作已经完成,即使它是ProgressWindow的新实例。请注意,在错误的版本上,“确定”按钮立即可见 - 而不是等待完成工作。

  3. 我想澄清“块1”中的代码。说实话,我完全不明白。这个部分真的很重要吗?我的意思是,我发现了很多例子(也在这个论坛上 - 例如here),其中没有包含此部分,用户报告解决方案有效。就我而言,没有这部分进度条根本不起作用,但也许我做错了。

3 个答案:

答案 0 :(得分:2)

  1. 调用CancelAsync会停止所有待处理的工作。但是如果工作已经开始,方法体需要检查是否调用了cancel。请参阅CancelAsync
  2.   

    CancelAsync提交终止待处理后台的请求   操作并将CancellationPending属性设置为true。

         

    当您调用CancelAsync时,您的工作方法有机会   停止执行并退出。 工作人员代码应定期检查   CancellationPending属性以查看它是否已设置为true。

    1. 我不知道。顺便说一句,图像不起作用。将其嵌入问题中。
    2. 代码分配一个方法,该方法在BackgroundWorker启动时执行,您可以连接方法以报告进度,并在后台工作完成后执行清理/更新。

答案 1 :(得分:1)

BackgroundWorker.CancelAsync经常被误解。它不会停止任何待处理的工作,但仅仅是向UI线程发出的工作已被取消的信号!它只是设置CancellationPending属性,您可以定期在DoWork轮询。

不幸的是,Thread.SleepDoWork次调用的MSDN示例非常愚蠢。通常,您在DoWork中调用阻止操作,这通常完全与UI无关。

有关更实用的示例,请参阅我的回答here

答案 2 :(得分:0)

1。 根据{{​​3}},也许你应该在循环中添加一个中断。

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        for (int i = 1; i <= 10; i++)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                // Perform a time consuming operation and report progress.
                System.Threading.Thread.Sleep(500);
                worker.ReportProgress(i * 10);
            }
        }
    }

2。 不知道。

3。 块1区域设置为BackgroundWorker事件。在我的情况下,如果我单击属性中的闪电图标来设置事件,它通常会出现在Form1.Designer.cs中。