为什么我必须使用(异步方法).Result而不是await (async方法)
本文关键字:方法 async await Result 异步方法 为什么 | 更新日期: 2023-09-27 18:12:37
我在mediasservices azure门户中启动了2个通道。启动一个通道需要很长时间才能完成,每个通道大约需要25-30秒。因此,多线程:)
然而,我不清楚以下内容:
我有两个方法:
public async Task<bool> StartAsync(string programName, CancellationToken token = default(CancellationToken))
{
var workerThreads = new List<Thread>();
var results = new List<bool>();
foreach (var azureProgram in _accounts.GetPrograms(programName))
{
var thread = new Thread(() =>
{
var result = StartChannelAsync(azureProgram).Result;
lock (results)
{
results.Add(result);
}
});
workerThreads.Add(thread);
thread.Start();
}
foreach (var thread in workerThreads)
{
thread.Join();
}
return results.All(r => r);
}
和
private async Task<bool> StartChannelAsync(IProgram azureProgram)
{
var state = _channelFactory.ConvertToState(azureProgram.Channel.State);
if (state == State.Running)
{
return true;
}
if (state.IsTransitioning())
{
return false;
}
await azureProgram.Channel.StartAsync();
return true;
}
在第一种方法中我使用
var result = StartChannelAsync(azureProgram).Result;
在这种情况下,一切都很好。但是如果我使用
var result = await StartChannelAsync(azureProgram);
没有等待执行,我的结果有零项。我遗漏了什么?
这是正确的方法吗?
感谢对代码的任何注释。我不是多线程之王;)
干杯!
不要跨新的Thread
实例并行执行任务,而是使用Task。WhenAll:
public async Task<bool> StartAsync(string programName, CancellationToken token = default(CancellationToken))
{
// Create a task for each program and fire them "at the same time"
Task<bool>[] startingChannels = _accounts.GetPrograms(programName))
.Select(n => StartChannelAsync(n))
.ToArray();
// Create a task that will be completed when all the supplied tasks are done
bool[] results = await Task.WhenAll(startingChannels);
return results.All(r => r);
}
注意:我看到你正在传递一个CancellationToken到你的StartAsync方法,但你实际上并没有使用它。考虑将它作为参数传递给StartChannelAsync,然后在调用azureProgram.Channel.StartAsync
如果你喜欢俏皮话:
public async Task<bool> StartAsync(string programName, CancellationToken token = default(CancellationToken))
{
return (await Task.WhenAll(_accounts.GetPrograms(programName)
.Select(p => StartChannelAsync(p))
.ToArray())).All(r => r);
}