我正在与后台工作者合作,但我既不能同步我的进度条也无法停止或中止该过程。
在我的dowork函数中
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();
}
}
现在我想知道如何同步进度条以及如何退出进程?
答案 0 :(得分:1)
您是否设置了BackgroundWorker.WorkerReportsProgress&&您的实例上的BackgroundWorker.WorkerSupportsCancellation属性为true
?
e.g。
var myBackgroundWorker = new BackgroundWorker();
myBackgroundWorker.WorkerReportsProgress = true;
myBackgroundWorker.WorkerSupportsCancellation = true;
//the rest of the init
如果您想报告进度,则需要在DoWork
内调用BackgroundWorker.ReportProgress()方法。
答案 1 :(得分:0)
这是一个垃圾和微不足道的答案,但给任务并行库一个旋转。 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
答案 2 :(得分:0)
(您可能需要查看this其他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用于保持代码紧凑。显然,您可以使用“普通”处理程序或其他任何将代码附加到您喜欢/想要/需要的事件的方法。