6

由于基于任务的异步模式现在是推荐的路线(根据 MSDN @ herehere),我将如何将hello world下面的简单代码转换为基于任务的异步模式?

让我们假设我对此一无所知Tasks,并且我试图演示工作人员的输入和输出以及从“主”调用。

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!";
    }
}
4

2 回答 2

4

这取决于您到底想要做什么异步。如果Thread.Sleep()代表一些 CPU 密集型工作,那么您不会从使用 TAP 中获得太多收益。

如果你想让等待内部DoWork()异步,这意味着将签名从更改stringasync Task<string>,然后使用await Task.Delay()而不是Thread.Sleep()

如果您还想进行Main()异步操作,则可以,如果您使用的是 C# 7.1 或更高版本。

如果您使用的是旧版本的 C#,那么它就变成了。您可以做的是在实际中创建异步MainAsync()然后同步。这意味着主线程将被阻塞,但我们需要它来保持应用程序处于活动状态。此外,将异步与同步混合通常不是一个好主意(尤其是因为它经常导致死锁),但在这种情况下没关系。Wait()Main()awaitWait()

如果我们使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!";
    }
}
于 2012-11-28T18:18:44.923 回答
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表示操作的对象。 task.Result将阻塞当前线程,直到DoWork()返回。

于 2012-11-28T07:25:09.577 回答