我在mediaservices 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);
不等待执行,我的结果是零条目。 我在这里缺少什么?
这是正确的方法吗?
对代码的任何评论都表示赞赏。我不是多线程的国王;)
干杯!
答案 0 :(得分:4)
请勿跨越新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);
}