3

我正在使用后台工作人员,但我既不能同步我的进度条,也不能停止或中止进程。

在我的工作功能中

void bw_DoWork(object sender, DoWorkEventArgs e)
{
    if(bw.CancellationPending==true)
    {
        e.cancel=true;
        return;
    }
    else
    {
        e.Result = abc();
    }
}
int abc()
{
    //my work
    Count++;
    return count;
}

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if(bw.CancellationPending==true)
    {
        button17.Visibility = Visibility.Visible;
        label1.Content = "Aborted";
    }
    button17.Visibility = Visibility.Visible;
    label1.Content = "Completed";
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
    if(bw.IsBusy)
    {
        bw.CancelAsync();
    }
}

现在我想知道如何同步我的进度条以及如何退出该过程?

4

3 回答 3

1

您是否将实例上的BackgroundWorker.WorkerReportsProgress && BackgroundWorker.WorkerSupportsCancellationtrue属性设置为?

例如

var myBackgroundWorker = new BackgroundWorker();
myBackgroundWorker.WorkerReportsProgress = true;
myBackgroundWorker.WorkerSupportsCancellation = true;
//the rest of the init

如果要报告进度,则需要DoWork.

于 2013-08-01T07:06:27.183 回答
0

(您可能想查看其他SO 问题/答案以了解有关新async设施的详细信息!它极大地提高了开发此类操作的生活质量!)

BackgroundWorker是基于事件的,基本用法如下(链接提供了许多有用的附加细节):

var worker = new BackgroundWorker();

// The following two props must be true:
// #1: The worker will be enabled to signal its progress
worker.WorkerReportsProgress = true;
// #2: The worker will accept cancellation
worker.WorkerSupportsCancellation = true;

// Now the events:

worker.DoWork += (s,e) => 
{         
    int i = 0; // This goes from 0 to 100
    // Do code, update 'i'
    worker.ReportProgress(i); 

    worker.CancelAsync();     //... to cancel the worker if needed

    // WARNING: This code *cannot* interact with the UI because
    // it's running in a different thread
};

worker.ProgressChanged += (s,e)=> 
{ 
// This is executed when you call ReportProgress() from DoWork() handler
// IMPORTANT: All UI interaction **must** happen here    

// e.ProgressPercentage gives you the value of the parameter you passed to
// ReportProgress() (this mechanism is a perfect fit for a progress bar!)
};

worker.RunWorkerCompleted+= (s,e) => 
{
    // code here runs when DoWork() is done, is canceled or throws.
    // To check what happened, the link provides this sample code:
    if (e.Cancelled == true)
    {
        // Cancelled!
    }
    else if (e.Error != null)
    {
        // Exception !
    }
    else
    {
        // Work completed!
    }
};

worker.RunWorkerAsync();

重要的是要知道(从上面的链接中提取):

您必须小心不要在 DoWork 事件处理程序中操作任何用户界面对象。相反,通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。

此处的更新Lambda 用于保持代码紧凑。您显然可以使用“普通”处理程序或任何其他将代码附加到您喜欢/想要/需要的事件的方法。

于 2013-08-01T07:16:52.623 回答
0

这是一个垃圾和微不足道的答案,但给 Task Parallel 库一个旋转。 http://msdn.microsoft.com/en-us/library/dd537608.aspx

该库将线程封装为离散的 Task 对象。它支持取消。

请注意,在工作线程中,工作代码本身必须通过轮询暂停/取消标志和令牌来支持暂停和取消操作。您不能仅使用线程安全地实现这些操作。

这是一个更好的模式

至于您的问题,需要 2 个标志来支持您的操作。您将需要在工作代码期间定期检查它们。

bool pause = false;
bool cancel = false;
void DoWork()
{
    try
    {
        ...
        //periodically check the flags
        if(cancel) return;
        while(paused){}; //spin on pause
        ...
    }
    finally
    {
        //cleanup operation
    }
}

Alastair Pitts 的回答说明了后台工作人员如何支持这些功能。MSDN 也是如此;) http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

于 2013-08-01T07:09:23.687 回答