简化后台工作者的匿名方法
Simplifying anonymous methods for background worker
我正在尝试通过按钮点击来制作我的所有代码,运行 在后台工作程序中。所以我有以下代码模板。
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerAsync();
while (backgroundWorker.IsBusy)
{
Application.DoEvents();
}
只是想知道是否有简化此代码的方法,所以我没有有效地为我的所有按钮复制相同的代码块。
编辑:
我尝试 运行 的典型代码是:
//Synchronous task
Wait(2000);
//Synchronous task
return taskResult ? "Success" : "Failure"
没有更多上下文,就不可能提出非常具体的改进建议。也就是说,您肯定可以摆脱 while
循环。只需使用:
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerAsync();
请注意,如果您有要在 BackgroundWorker
任务完成时执行的代码(可能解释为什么您首先有 while
循环),这样的事情会起作用(而不是使用之前的 while
循环):
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerCompleted += (sender, e) =>
{
// code to execute when background task is done
};
backgroundWorker.RunWorkerAsync();
在现代 C# 中,BackgroundWorker
几乎已过时。它现在提供的主要好处是方便的进度报告,实际上可以通过使用 Progress<T>
.
轻松获得。
如果您不需要报告进度,分解您的代码以使用 async
/await
很容易:
await Task.Run(() =>
{
//code
});
// code to execute when background task is done
如果您确实需要报告进度,只是稍微困难一点:
Progress<int> progress = new Progress<int>();
progress.ProgressChanged += (sender, progressValue) =>
{
// do something with "progressValue" here
};
await Task.Run(() =>
{
//code
// When reporting progress ("progressValue" is some hypothetical
// variable containing the progress value to report...Progress<T>
// is generic so you can customize to do whatever you want)
progress.Report(progressValue);
});
// code to execute when background task is done
最后,在某些情况下,您可能需要任务 return 一个值。在那种情况下,它看起来更像这样:
var result = await Task.Run(() =>
{
//code
// "someValue" would be a variable or expression having the value you
// want to return. It can be of any type.
return someValue;
});
// At this point in execution "result" now has the value returned by the
// background task. Note that in the above example, the method itself
// is anonymous and so you could just set a local variable at the end of the
// task; the value-returning syntax is more useful when you are calling an
// actual method that itself returns a value, and is especially useful when
// you are calling an `async` method that returns a value (i.e. you're not
// even using `Task.Run()` in the `await` statement.
// code to execute when background task is done
您可以根据需要混合搭配上述技巧。
我正在尝试通过按钮点击来制作我的所有代码,运行 在后台工作程序中。所以我有以下代码模板。
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerAsync();
while (backgroundWorker.IsBusy)
{
Application.DoEvents();
}
只是想知道是否有简化此代码的方法,所以我没有有效地为我的所有按钮复制相同的代码块。
编辑: 我尝试 运行 的典型代码是:
//Synchronous task
Wait(2000);
//Synchronous task
return taskResult ? "Success" : "Failure"
没有更多上下文,就不可能提出非常具体的改进建议。也就是说,您肯定可以摆脱 while
循环。只需使用:
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerAsync();
请注意,如果您有要在 BackgroundWorker
任务完成时执行的代码(可能解释为什么您首先有 while
循环),这样的事情会起作用(而不是使用之前的 while
循环):
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerCompleted += (sender, e) =>
{
// code to execute when background task is done
};
backgroundWorker.RunWorkerAsync();
在现代 C# 中,BackgroundWorker
几乎已过时。它现在提供的主要好处是方便的进度报告,实际上可以通过使用 Progress<T>
.
如果您不需要报告进度,分解您的代码以使用 async
/await
很容易:
await Task.Run(() =>
{
//code
});
// code to execute when background task is done
如果您确实需要报告进度,只是稍微困难一点:
Progress<int> progress = new Progress<int>();
progress.ProgressChanged += (sender, progressValue) =>
{
// do something with "progressValue" here
};
await Task.Run(() =>
{
//code
// When reporting progress ("progressValue" is some hypothetical
// variable containing the progress value to report...Progress<T>
// is generic so you can customize to do whatever you want)
progress.Report(progressValue);
});
// code to execute when background task is done
最后,在某些情况下,您可能需要任务 return 一个值。在那种情况下,它看起来更像这样:
var result = await Task.Run(() =>
{
//code
// "someValue" would be a variable or expression having the value you
// want to return. It can be of any type.
return someValue;
});
// At this point in execution "result" now has the value returned by the
// background task. Note that in the above example, the method itself
// is anonymous and so you could just set a local variable at the end of the
// task; the value-returning syntax is more useful when you are calling an
// actual method that itself returns a value, and is especially useful when
// you are calling an `async` method that returns a value (i.e. you're not
// even using `Task.Run()` in the `await` statement.
// code to execute when background task is done
您可以根据需要混合搭配上述技巧。