我有一个问题,如果我运行Main方法,并在其中调用(GetRankedEditorsPickList),它将异步运行,但如果运行(GetRankedEditorsPickList1),则将按顺序运行。您可以查看托管的threadId和结果。
有人可以告诉我为什么吗?这是linqpad代码。
async Task Main()
{
List<string> y = new List<string>() { "a","b","c" };
var rankedFeedBatchTasks = y.Select(async (batch, index) =>
{
return new
{
Index = index,
RankedList = await GetRankedEditorsPickList1(batch).ConfigureAwait(false)
};
}).ToList();
var rankedFeedBatches = await Task.WhenAll(rankedFeedBatchTasks);
"Completed".Dump();
}
async Task<string> GetRankedEditorsPickList(string batch)
{
$"Started + {Environment.CurrentManagedThreadId}".Dump();
await Task.Delay(TimeSpan.FromSeconds(5));
batch = batch + "1";
$"Ended + {Environment.CurrentManagedThreadId}".Dump();
return batch;
}
// Define other methods and classes here
Task<string> GetRankedEditorsPickList1(string batch)
{
$"Started + {Environment.CurrentManagedThreadId}".Dump();
Thread.Sleep(TimeSpan.FromSeconds(5));
batch = batch + "1";
$"Ended + {Environment.CurrentManagedThreadId}".Dump();
return Task.FromResult(batch);
}
第一个方法调用结果::
Started + 11
Started + 11
Started + 11
Ended + 10
Ended + 13
Ended + 14
Completed
第二种方法调用结果::
Started + 11
Ended + 11
Started + 11
Ended + 11
Started + 11
Ended + 11
已完成
答案 0 :(得分:3)
GetRankedEditorsPickList
是异步函数,而GetRankedEditorsPickList1
不是异步函数。这就是为什么后者顺序运行的原因。
更具体地说:
Task.Delay
不同,Thread.Sleep
不是异步的。答案 1 :(得分:1)
建议您阅读 Stephen Cleary的“ C#烹饪书中的并发性” ,在本书中给出了解释和使用Task.FromResult
的方式
问题 您需要使用异步签名来实现同步方法。这个 如果您从异步接口或基类继承,则会出现这种情况 但希望同步实施。当单位 当需要简单的存根或模拟异步时,测试异步代码 界面。
解决方案 您可以使用Task.FromResult创建并返回一个已经完成的新Task 具有指定值
Task.FromResult(batch)返回已完成的任务,这就是为什么GetRankedEditorsPickList1被同步执行
答案 2 :(得分:0)
异步并不意味着并行。异步用于克服顺序执行(即,如果您不希望以顺序方式执行某些任务,则可以使用异步)