繁体   English   中英

为什么我必须使用(异步方法).result而不是等待(异步方法)?

[英]Why do I have to use (async method).result instead of await (async method)?

我正在mediaservices azure门户中启动2个频道。 启动频道需要很长时间才能完成,每个频道大约需要25-30秒。 因此,多线程:)

但是,我不清楚以下内容:

我有2种方法:

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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM