【问题标题】:How to get asynchronousy without new threads or async and await keywords but only Task如何在没有新线程或 async 和 await 关键字但只有 Task 的情况下获得异步
【发布时间】:2012-10-15 07:42:52
【问题描述】:

我想知道如何在不使用额外线程或awaitasync 关键字但仅使用任务的情况下完成以下程序所做的相同事情。一个示例代码会很棒。在我看来,我们需要使用 TaskCompletionSourceAsync 版本的 IO 绑定操作或任何长时间运行的操作。

static void Main(string[] args)
{
  Task t = Go();
  Console.WriteLine("Hello World");
  Task.Delay(1000).GetAwaiter().OnCompleted(() => { Console.WriteLine("Completed"); });
  Console.ReadLine();
}

static async Task Go()
{
  var task = PrintAnswerToLife();
  await task;
  Console.WriteLine("Done");
}

static async Task PrintAnswerToLife()
{
  var task = GetAnswerToLife();
  int answer = await task;
  Console.WriteLine(answer);
}

static async Task<int> GetAnswerToLife()
{
  var task = Task.Delay(2000);
  await task;
  int answer = 21 * 2;
  return answer;
}

【问题讨论】:

标签: c# .net asynchronous async-await


【解决方案1】:

您可以使用ContinueWithasync / await 直接转换为Task。其他翻译也是可能的,例如,Task.Delay 变为 System.Threading.Timer

基本模式是,对于任何执行awaitasync 方法:

static async Task Go()
{
  var task = PrintAnswerToLife();
  await task;
  Console.WriteLine("Done");
}

变成:

static Task Go()
{
  var tcs = new TaskCompletionSource<object>();
  var task = PrintAnswerToLife();
  task.ContinueWith(_ =>
  {
    Console.WriteLine("Done");
    tcs.SetResult(null);
  });
  return tcs.Task;
}

正确的错误处理需要更多的工作。

【讨论】:

  • 其实还有一件事,ContinueWith 应该在与原方法相同的同步上下文中工作。
  • 好收获。在这个例子中,没关系,但通常ContinueWith应该取TaskScheduler.FromCurrentSynchronizationContext
猜你喜欢
  • 1970-01-01
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 2013-05-14
  • 2023-03-12
  • 2018-06-04
  • 2021-06-07
相关资源
最近更新 更多