【发布时间】:2019-08-13 10:16:02
【问题描述】:
我试图理解Async/Await 编程模型。我写了一个示例程序来理解这一点。
我编写了 3 个独立的异步方法,分别命名为 GetFirstValue、GetSecondValue、GetThirdValue。
有一个名为M1的方法,它异步执行上述3个方法,并返回上述3个方法的拼接结果。
我的主要想法是,如果方法 GetFirstValue 需要 5 秒,GetSecondValue 需要 7 秒,GetThirdValue 需要 8 秒。然后,M1 应该会在 20 秒内返回。由于这 3 种方法不同步。
但是因为我没有正确理解这个概念。我做错了什么。这是我正在研究的完整程序。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LearningAsyncProgramming
{
class Program
{
static void Main(string[] args)
{
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
AsyncMethodsClass asyncMethods = new AsyncMethodsClass();
Console.WriteLine(asyncMethods.M1().Result);
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds/1000);
}
}
class AsyncMethodsClass
{
public async Task<string> M1()
{
string retVal = string.Empty;
int v1 = await GetFirstValue();
int v2 = await GetSecondValue();
int v3 = await GetThirdValue();
return string.Concat( v1,"-",v2,"-",v3);
}
private async Task<int> GetFirstValue()
{
int a = await GetTimer();
return a;
}
private async Task<int> GetSecondValue()
{
int a = await GetTimer();
return a;
}
private async Task<int> GetThirdValue()
{
int a = await GetTimer();
return a;
}
private async Task<int> GetTimer()
{
int someNumber = new Random().Next(5,9);
Thread.Sleep(someNumber * 1000);
return someNumber;
}
}
}
这是实施答案中的建议后的更新代码。它完全符合我的预期。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LearningAsyncProgramming
{
class Program
{
static void Main(string[] args)
{
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
AsyncMethodsClass asyncMethods = new AsyncMethodsClass();
Console.WriteLine(asyncMethods.M1().Result);
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds/1000);
}
}
class AsyncMethodsClass
{
public async Task<string> M1()
{
// Start all the functions, but don't wait just yet
var t1 = GetFirstValue();
var t2 = GetSecondValue();
var t3 = GetThirdValue();
return string.Concat( await t1,"-",await t2,"-",await t3);
}
private async Task<int> GetFirstValue()
{
int a = await GetTimer();
return a;
}
private async Task<int> GetSecondValue()
{
int a = await GetTimer();
return a;
}
private async Task<int> GetThirdValue()
{
int a = await GetTimer();
return a;
}
private async Task<int> GetTimer()
{
int someNumber = new Random().Next(5,9);
await Task.Delay(someNumber * 1000);
return someNumber;
}
}
}
【问题讨论】:
-
在任务中使用
Thread.Sleep不是一个好主意,请改用await Task.Delay(...)。 -
“我做错了什么”,你能详细说明你为什么这么说吗?这里有什么不符合您的期望?除了我上面提到的 Thread.Sleep 之外,我个人肯定会在这里做一些不同的事情,但这不会使它们出错,但是知道你打算代码做什么,和/或你期望它做什么,它没有/没有,将帮助我们为您的问题制定最佳/正确答案。
-
如果“有什么问题”是您期望三个调用并行运行,本质上 M1 的执行时间应该与三个调用中最长的一样长,那么答案是您调用了每个调用,在你打电话给下一个之前等待他们回来。而是检查@Lukas 提供的答案,它可能正是您想要的。
-
这个video 真的帮助我理解了等待的正确用法以及在制作/使用异步方法时会发生什么。
-
@LasseVågsætherKarlsen 是的,你的第三条评论就是我想要的。我想并行运行所有 3 个方法,并在所有方法完成执行后返回结果。
标签: c# .net multithreading async-await