[英]C# BackgroundWorker.CancelAsync() vs DoWorkEventArgs.Cancel
I want to use the RunWorkerCompletedEventArgs.Cancelled
value in my BackgroundWorker completed handler, but the documentation isn't clear how how BackgroundWorker.CancelAsync()
and DoWorkEventArgs.Cancel
(in the background worker do work handler) will each effect it.我想在我的 BackgroundWorker 完成的处理程序中使用
RunWorkerCompletedEventArgs.Cancelled
值,但文档不清楚BackgroundWorker.CancelAsync()
和DoWorkEventArgs.Cancel
(在后台工作人员执行工作处理程序中)将如何影响它。 Are they functionally the same?它们在功能上是否相同?
For example, is this...例如,这是...
private void _Worker_DoWork(object sender, DoWorkEventArgs e)
{
(sender as BackgroundWorker).CancelAsync();
}
...equivalent to this? ……相当于这个?
private void _Worker_DoWork(object sender, DoWorkEventArgs e)
{
e.Cancel = true;
}
Will the latter result in subsequent evaluations of CancellationPending()
to evaluate as true?后者是否会导致后续对
CancellationPending()
的评估结果为真? Also, if the background worker is cancelled externally (ie myBW.CancelAsync();
outside the do work handler), will e.Cancel = false
cause an evaluation of CancellationPending()
to be false?此外,如果后台工作人员在外部被取消(即
myBW.CancelAsync();
在 do 工作处理程序之外), e.Cancel = false
是否会导致对CancellationPending()
的评估为假?
BackgroundWorker.CancelAsync()
will set the value of BackgroundWorker.CancellationPending
to true, so the DoEvent code can check it. BackgroundWorker.CancelAsync()
会将BackgroundWorker.CancellationPending
的值设置为 true,因此 DoEvent 代码可以检查它。
DoWorkEventArgs.Cancel
is there to tell RunWorkerCompleted Event that the process was Canceled. DoWorkEventArgs.Cancel
用于告诉 RunWorkerCompleted Event 进程已取消。 You are not supposed to use the result of a operation that was aborted or ended in Exception.您不应该使用被中止或以异常结束的操作的结果。 Setting
DoWorkEventArgs.Cancel
to true will set RunWorkerCompletedEventArgs.Canceled
to true.将
RunWorkerCompletedEventArgs.Canceled
DoWorkEventArgs.Cancel
为 true。 Wich will also force RunWorkerCompletedEventArgs.Result
to throw an exception if accessed .如果访问,Wich 还将强制
RunWorkerCompletedEventArgs.Result
抛出异常。
I have some pretty old example code from when I learned Multithrading with BGW.当我使用 BGW 学习多线程时,我有一些非常古老的示例代码。 It should help you.
它应该可以帮助你。
#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
if (!bgwPrim.IsBusy)
{
//Prepare ProgressBar and Textbox
int temp = (int)nudPrim.Value;
pgbPrim.Maximum = temp;
tbPrim.Text = "";
//Start processing
bgwPrim.RunWorkerAsync(temp);
}
}
private void btnPrimCancel_Click(object sender, EventArgs e)
{
if (bgwPrim.IsBusy)
{
bgwPrim.CancelAsync();
}
}
private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
int highestToCheck = (int)e.Argument;
//Get a reference to the BackgroundWorker running this code
//for Progress Updates and Cancelation checking
BackgroundWorker thisWorker = (BackgroundWorker)sender;
//Create the list that stores the results and is returned by DoWork
List<int> Primes = new List<int>();
//Check all uneven numbers between 1 and whatever the user choose as upper limit
for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
{
//Report progress
thisWorker.ReportProgress(PrimeCandidate);
bool isNoPrime = false;
//Check if the Cancelation was requested during the last loop
if (thisWorker.CancellationPending)
{
//Tell the Backgroundworker you are canceling and exit the for-loop
e.Cancel = true;
break;
}
//Determin if this is a Prime Number
for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
{
if (PrimeCandidate % j == 0)
isNoPrime = true;
}
if (!isNoPrime)
Primes.Add(PrimeCandidate);
}
//Tell the progress bar you are finished
thisWorker.ReportProgress(highestToCheck);
//Save Return Value
e.Result = Primes.ToArray();
}
private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pgbPrim.Value = e.ProgressPercentage;
}
private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pgbPrim.Value = pgbPrim.Maximum;
this.Refresh();
if (!e.Cancelled && e.Error == null)
{
//Show the Result
int[] Primes = (int[])e.Result;
StringBuilder sbOutput = new StringBuilder();
foreach (int Prim in Primes)
{
sbOutput.Append(Prim.ToString() + Environment.NewLine);
}
tbPrim.Text = sbOutput.ToString();
}
else
{
tbPrim.Text = "Operation canceled by user or Exception";
}
}
#endregion
Personally I consider the BackgroundWorker class in a GUI to be good Multitasking "Training Wheels".我个人认为 GUI 中的 BackgroundWorker class 是很好的多任务“训练轮”。
No, they are not the same.不,它们不一样。 The "CancelAsync()" method runs from outside of the "backgroundworker"'s code.
“CancelAsync()”方法从“backgroundworker”的代码之外运行。 The "CancellationPending" can be check in the "DoWork" body and "e.Cancel" is set in "DoWork" to be used in the "Completed" method.
可以在“DoWork”主体中检查“CancellationPending”,并在“DoWork”中设置“e.Cancel”以在“Completed”方法中使用。
Please see the page below for more information:请参阅以下页面了解更多信息:
( https://www.c-sharpcorner.com/uploadfile/mahesh/backgroundworker-in-C-Sharp/ ) ( https://www.c-sharpcorner.com/uploadfile/mahesh/backgroundworker-in-C-Sharp/ )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.