Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将此BackgroundWorker更新为async/await?_C#_Asynchronous - Fatal编程技术网

C# 如何将此BackgroundWorker更新为async/await?

C# 如何将此BackgroundWorker更新为async/await?,c#,asynchronous,C#,Asynchronous,我正在尝试将一些BackgroundWorkers转换为较新的async/await,而我的同事和我都不知道如何执行以下操作:目前,我的代码大致如下所示: // Note the override. This method isn't async and I don't own the base class protected override void MyMethod() { backgroundWorker1.RunWorkerAsync(); } private void ba

我正在尝试将一些BackgroundWorkers转换为较新的async/await,而我的同事和我都不知道如何执行以下操作:目前,我的代码大致如下所示:

// Note the override. This method isn't async and I don't own the base class
protected override void MyMethod()
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    DoStuff1();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    DoStuff2();
}
protected override async void MyNewMethod()
{
  try
  {
    await Task.Run(() => DoStuff1());
    DoSuccessStuff2();
  }
  catch (Exception ex)
  {
    DoErrorStuff2();
  }
}
protected override async Task MyNewMethodAsync()
{
  await Task.Run(() => DoStuff1());
  DoSuccessStuff2();
}
我希望将代码更新为如下所示,但显然这不起作用,因为我需要从同步方法调用它:

// Again note the override. This method isn't async and I don't own the base class
protected override void MyNewMethod()
{
    // Error: "The 'await' operator can only be used within an async method."
    await Task.Run((Action)DoStuff1);
    DoStuff2();
}
有没有办法做到这一点?我走错方向了吗? 主要问题是MyMethod()不应该是异步的,但我发现的任何其他帖子都只是说将其更改为异步。即使我可以,这也意味着调用它的方法也必须是异步的,调用该方法的方法也必须是异步的,等等。所以基本上,所有的东西都变成异步的,只是为了支持这个方法。我相信有更好的办法


任何帮助都将不胜感激,谢谢

现有代码的简单翻译如下:

// Note the override. This method isn't async and I don't own the base class
protected override void MyMethod()
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    DoStuff1();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    DoStuff2();
}
protected override async void MyNewMethod()
{
  try
  {
    await Task.Run(() => DoStuff1());
    DoSuccessStuff2();
  }
  catch (Exception ex)
  {
    DoErrorStuff2();
  }
}
protected override async Task MyNewMethodAsync()
{
  await Task.Run(() => DoStuff1());
  DoSuccessStuff2();
}
理想情况下,你应该这样做。这个解决方案的缺点是
MyNewMethod
现在是一个“顶级”方法-它必须处理自己的所有错误和一切。然而,由于旧的BGW代码也有同样的问题,这至少是朝着正确方向迈出的一步

所以基本上所有的东西都是异步的,只是为了支持这个方法。我相信有更好的办法

实现这一点可能会很尴尬,但如果您一直使用“
async
”,那么编写和测试异步代码就容易多了。大概是这样的:

// Note the override. This method isn't async and I don't own the base class
protected override void MyMethod()
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    DoStuff1();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    DoStuff2();
}
protected override async void MyNewMethod()
{
  try
  {
    await Task.Run(() => DoStuff1());
    DoSuccessStuff2();
  }
  catch (Exception ex)
  {
    DoErrorStuff2();
  }
}
protected override async Task MyNewMethodAsync()
{
  await Task.Run(() => DoStuff1());
  DoSuccessStuff2();
}

这会将错误处理向上推到调用
MyNewMethodAsync
的人。此外,
MyNewMethodAsync
现在可以从其他异步方法进行测试和组合。

您走错了路。你可以使用WaitHandle来阻止(使用WaitOne),并让BackgroundWorker在工作完成时设置WaitHandle。我不希望代码被阻止。其目的是在不冻结UI的情况下进行长时间的数据库加载(5-10秒)。您的原始代码应该这样做。看起来您需要后台工作人员在DoStuff之前完成。因此您确实需要阻止。原始代码工作正常,RunWorkerAsync不会阻止从中调用它的线程。您可以在“override”之后添加“async”,这不会更改方法的签名–async关键字基本上只是启用Wait关键字的标记。或者,您可以编写“Task.Run(DoStuff1).ContinueWith(Task=>DoStuff2(),TaskContinuationOptions.OnlyOnRanToCompletion);”,它省略了asynchronous/await关键字,但在功能上与您编写的相同。是的,这个方法不能等待,但是你不需要考虑它看起来不像以前有人等过你的后台工作人员。