我想在我的BackgroundWorker完成的处理程序中使用RunWorkerCompletedEventArgs.Cancelled
值,但是文档尚不清楚BackgroundWorker.CancelAsync()
和DoWorkEventArgs.Cancel
(在后台工作程序中如何执行工作处理程序)如何分别影响它。它们在功能上是否相同?
例如,这是...
private void _Worker_DoWork(object sender, DoWorkEventArgs e)
{
(sender as BackgroundWorker).CancelAsync();
}
...相当于这个?
private void _Worker_DoWork(object sender, DoWorkEventArgs e)
{
e.Cancel = true;
}
后者将导致随后对CancellationPending()
的评估为“真”吗?另外,如果后台工作人员在外部被取消(即,在工作处理程序外部的myBW.CancelAsync();
),e.Cancel = false
是否会使CancellationPending()
的评估为假?
[BackgroundWorker.CancelAsync()
会将BackgroundWorker.CancellationPending
的值设置为true,因此DoEvent代码可以对其进行检查。
DoWorkEventArgs.Cancel
可以告诉RunWorkerCompleted Event该进程已取消。您不应使用在Exception中中止或结束的操作的结果。将DoWorkEventArgs.Cancel
设置为true将将RunWorkerCompletedEventArgs.Canceled
设置为true。 Wich也会将RunWorkerCompletedEventArgs.Result
强制为throw an exception if accessed。
我从BGW学习Multithrading时获得了一些非常古老的示例代码。它应该可以帮助您。
#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
我个人认为GUI中的BackgroundWorker类是很好的多任务“训练轮子”。
不,他们不一样。 “ CancelAsync()”方法从“ backgroundworker”的代码外部运行。可以在“ DoWork”主体中检查“ CancellationPending”,并在“ DoWork”中设置“ e.Cancel”以在“ Completed”方法中使用。请参阅下面的页面以获取更多信息:(https://www.c-sharpcorner.com/uploadfile/mahesh/backgroundworker-in-C-Sharp/)