在过去的几天里,我测试了.net 4.5和c#5的新功能.
我喜欢它的新async/await功能.之前我曾使用BackgroundWorker通过响应式UI在后台处理更长的进程.
我的问题是:在拥有这些不错的新功能之后,我何时应该使用async/await和什么时候使用BackgroundWorker?两者的常见情况是什么?
c# backgroundworker task-parallel-library async-await .net-4.5
我想显示在外部库中执行的计算进度.
例如,如果我有一些计算方法,并且我想在我的Form类中使用它为100000个值,我可以写:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Caluculate(int i)
{
double pow = Math.Pow(i, i);
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Maximum = 100000;
progressBar1.Step = 1;
for(int j = 0; j < 100000; j++)
{
Caluculate(j);
progressBar1.PerformStep();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我应该在每次计算后执行步骤.但是,如果我在外部方法中执行所有100000计算,该怎么办?如果我不想让这个方法依赖于进度条,我什么时候应该"执行步骤"?例如,我可以写
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void CaluculateAll(System.Windows.Forms.ProgressBar progressBar)
{
progressBar.Maximum = 100000;
progressBar.Step = 1;
for(int j = 0; …Run Code Online (Sandbox Code Playgroud) 我没有看到C#(和VB)的新异步功能和.NET 4.0的任务并行库之间存在差异.举个例子来说,埃里克利珀的代码从这里:
async void ArchiveDocuments(List<Url> urls) {
Task archive = null;
for(int i = 0; i < urls.Count; ++i) {
var document = await FetchAsync(urls[i]);
if (archive != null)
await archive;
archive = ArchiveAsync(document);
}
}
Run Code Online (Sandbox Code Playgroud)
似乎该await关键字有两个不同的用途.第一个出现(FetchAsync)似乎意味着,"如果稍后在方法中使用此值并且其任务未完成,请等到它完成后再继续." 第二个实例(archive)似乎意味着,"如果此任务尚未完成,请立即等待直到完成." 如果我错了,请纠正我.
难道不能像这样容易写吗?
void ArchiveDocuments(List<Url> urls) {
for(int i = 0; i < urls.Count; ++i) {
var document = FetchAsync(urls[i]); // removed await
if (archive != null) …Run Code Online (Sandbox Code Playgroud) 我在我的wpf应用程序中使用BackgroundWorker进行线程化.但它使UI挂起,因为我无法点击UI的任何地方.这是我的代码片段:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
Dispatcher.Invoke(new Action(() => ConnectFtp()));
};
worker.RunWorkerAsync();
}
private void ConnectFtp()
{
try
{
int port = string.IsNullOrEmpty(txtport.Text) ? 21 : Convert.ToInt32(txtport.Text);
if (ftpserver1 == null)
{
ftpserver1 = new FtpClient(txtftpserver.Text, port);
ftpserver1.ServerResponse += new EventHandler<FtpResponseEventArgs>(ftpserver2_ServerResponse);
ftpserver1.ClientRequest += new EventHandler<FtpRequestEventArgs>(ftpserver2_ClientRequest);
ftpserver1.TransferProgress += new EventHandler<TransferProgressEventArgs>(ftpserver2_TransferProgress);
ftpserver1.TransferComplete += new EventHandler<TransferCompleteEventArgs>(ftpserver2_TransferComplete);
}
if (!ftpserver1.IsConnected)
{
Run r = new Run("Server1 Status: Resolving address of …Run Code Online (Sandbox Code Playgroud)