由于基于任务的异步模式现在是推荐的路由(每个MSDN @ here和here),我如何将下面的简单hello world
代码转换为任务 - 基于异步模式?
让我们假设我对Tasks
一无所知,我试图向工作人员演示输入和输出,以及从'main'调用。
class Program
{
static void Main(string[] args)
{
Worker wk = new Worker();
string result = wk.DoWork(1000);
Console.WriteLine(result);
Console.WriteLine("Main says, Hello World!");
Console.ReadLine();
}
}
class Worker
{
public string DoWork(int delay)
{
Console.WriteLine("Worker says, working ...");
Thread.Sleep(delay); // represents the 100ms+ workload
return "Worker says, I'm done! Hello World!";
}
}
答案 0 :(得分:3)
这取决于你想要做什么异步。如果Thread.Sleep()
代表一些受CPU限制的工作,那么使用TAP就不会有太大的收获。
如果您想让DoWork()
内的等待异步,则意味着将签名从string
更改为async Task<string>
,然后使用await Task.Delay()
代替Thread.Sleep()
如果您还想使Main()
异步,则会更复杂,因为Main()
实际上不能async
。相反,您可以为真实MainAsync()
中的异步Wait()
创建异步Main()
,然后同步await
。这意味着主线程将被阻止,但我们需要保持应用程序活着。此外,将异步Wait()
与同步Main()
混合通常不是一个好主意(特别是因为它经常导致死锁),但在这种情况下它没关系。
如果我们使ReadLine()
异步,那么阻塞Console.ReadLineAsync()
也是异步的。没有Console.In
,但我们可以使用class Program
{
static void Main()
{
MainAsync().Wait();
}
static async Task MainAsync()
{
var worker = new Worker();
string result = await worker.DoWork(1000);
Console.WriteLine(result);
Console.WriteLine("Main says, Hello World!");
await Console.In.ReadLineAsync();
}
}
class Worker
{
public async Task<string> DoWork(int delay)
{
Console.WriteLine("Worker says, working ...");
await Task.Delay(delay); // represents the 100ms+ workload
return "Worker says, I'm done! Hello World!";
}
}
。
所以,最终的代码看起来像这样:
{{1}}
答案 1 :(得分:2)
我知道你想在一个单独的线程上执行DoWork()
并返回结果。虽然没有意义,因为线程在这个例子中不会实现任何东西,但下面是代码。
class Program
{
static void Main(string[] args)
{
Worker wk = new Worker();
Task<string> task = Task.Factory.StartNew(() => wk.DoWork(1000));
Console.WriteLine(task.Result);
Console.WriteLine("Main says, Hello World!");
Console.ReadLine();
}
}
Task.Factory.StartNew()
接受委托并立即开始在单独的线程上执行它。它返回一个表示操作的Task
对象。 <{1}}将阻止当前线程,直到task.Result
返回。