【问题标题】:Understanding Async and await in .Net了解 .Net 中的异步和等待
【发布时间】:2021-12-31 07:35:32
【问题描述】:

从下面的示例中,我无法理解为什么 asyncawait 在第一个示例中不起作用但在第二个示例中起作用。

第一个例子:

public static async Task Main(string[] args)
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();

    Console.WriteLine("started");
    var i =  await GetIntAsync(10);
    var j = await  GetstringAsync("abc");
    Console.WriteLine($"int {i}, string {j}");

    stopWatch.Stop();
    Console.WriteLine("RunTime " + stopWatch.ElapsedMilliseconds);
}

第二个例子:

public static async Task Main(string[] args)
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();

    Console.WriteLine("started");
    var i =   GetIntAsync(10);
    var j =   GetstringAsync("abc");
    await i; await j;
    Console.WriteLine($"int {i.Result}, string {j.Result}");

    stopWatch.Stop();
    Console.WriteLine("RunTime " + stopWatch.ElapsedMilliseconds);
}

GetIntAsync方法:

public static async Task<int> GetIntAsync(int i)
{
    Console.WriteLine("in get int waiting 3 sec's");
    await Task.Run(() =>
    {
        Thread.Sleep(3000);
        Console.WriteLine("int wait complete");
    });
    return i;
}

GetstringAsync方法

public static async Task<string> GetstringAsync(string i)
{
    Console.WriteLine("in get int waiting 6 sec's");
    await Task.Run(() =>
    {
        Thread.Sleep(6000);
        Console.WriteLine("string wait complete");
    });
    return i;
}

【问题讨论】:

  • “为什么 async 和 await 在第一个示例中不起作用” - 您能否提供更多详细信息?什么不起作用(您期望什么以及实际结果是什么)?看看你的例子,两个版本似乎都不错。
  • @RomanDoskoch 措辞不佳的问题,但 Thread.Sleeps 似乎表明 OP 想要并发,而不是异步。
  • 我期待 GetIntAsync 和 GetStringAsync 在两个示例中并行运行@RomanDoskoch
  • 仅供参考,而不是 Thread.Sleep 里面的 Task.Run 你可以做 await Task.Delay(6000);

标签: c# .net async-await task


【解决方案1】:

您似乎误解了asyncawait 的作用。常见的误解。

Async Await 不是并发。

我怀疑您希望 GetIntAsync 和 GetstringAsync 应该并行运行。

在 Rx Marble 图表中的含义:

---o
-------o

你在哪里找到的:

---o
    ------o

让我们分解一下你实际写的内容。

var i =  await GetIntAsync(10);
var j = await  GetstringAsync("abc");

可以扩展为:

var taskI = GetIntAsync(10);
var i = await taskI;
var taskJ = GetstringAsync("abc");
var j = await taskJ;

注意你启动taskI,等待它完成,然后你启动taskJ,然后等待它完成。

如示例 2(重新格式化后):

var taskI =   GetIntAsync(10);
var taskJ =   GetstringAsync("abc");
var i = await taskI; 
var j = await taskJ;

注意排序的变化。

仅供参考:你也可以这样做

https://stackoverflow.com/a/40938652/1808494

public static class TaskEx
{
    public static async Task<(T1, T2)> WhenAll<T1, T2>(Task<T1> task1, Task<T2> task2)
    {
        return (await task1, await task2);
    }
}

var (i, j) = await TaskEx.WhenAll(
                 GetIntAsync(10),
                 GetstringAsync("abc"));

【讨论】:

    猜你喜欢
    • 2016-06-18
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    相关资源
    最近更新 更多