首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等待异步操作

等待异步操作
EN

Stack Overflow用户
提问于 2017-11-09 15:43:09
回答 1查看 49关注 0票数 2

我有一个静态的泛型方法,用于并行地对集合执行一个操作(不要担心节流;我已经讨论过了;这里的代码是哑巴版本):

代码语言:javascript
复制
public static IEnumerable<Task> RunAllAsync<T>(this IEnumerable<T> enumerable, Action<T> action)
{
    var tasks = new List<Task>();
    foreach (var t in enumerable)
    {
        tasks.Add(Task.Run(() => action(t)));
    }
    return tasks;
}

下面是一个如何使用的示例:

代码语言:javascript
复制
public async Task UsageSync()
{
    var numbers = Enumerable.Range(1, 5);
    var random = new Random();
    var tasks = numbers.RunAllAsync(i =>
                                    {
                                        Console.WriteLine($"A {i}");
                                        Thread.Sleep(random.Next(1000));
                                        Console.WriteLine($"B {i}");
                                    });
    Console.WriteLine("Awaiting end");
    await Task.WhenAll(tasks.ToArray());
    Console.WriteLine("awaited");
    Thread.Sleep(2000);
    Console.WriteLine("Finished");
}

输出:

代码语言:javascript
复制
Awaiting end
A 4
A 5
A 1
A 2
A 3
B 3
B 2
B 1
B 5
B 4
awaited
Finished

一切如愿以偿。但是,现在我们将该操作本身设置为异步委托:

代码语言:javascript
复制
public async Task UsageAsync()
{
    var numbers = Enumerable.Range(1, 5);
    var random = new Random();
    var tasks = numbers.RunAllAsync(async i =>
                                    {
                                        Console.WriteLine($"A {i}");
                                        await Task.Run(() =>
                                                       {
                                                           Console.WriteLine($"B {i}");
                                                           Thread.Sleep(random.Next(1000));
                                                           Console.WriteLine($"C {i}");
                                                       });
                                    });
    Console.WriteLine("Awaiting end");
    await Task.WhenAll(tasks.ToArray());
    Console.WriteLine("awaited");
    Thread.Sleep(2000);
    Console.WriteLine("Finished");
}

输出:

代码语言:javascript
复制
Awaiting end
A 4
B 4
A 1
A 5
A 3
A 2
B 2
awaited
B 5
B 1
B 3
C 3
C 2
C 1
C 5
C 4
Finished

看到了吗?在线程完成之前,这个方法达到了“等待”!

我应该做些什么来确保等待异步操作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-09 15:51:52

由于您处理的是Action<T>,所以async i => { ... }会被转换为async void方法。async void的设计使它不可能等待它完成。将参数更改为Func<T, Task> func,并将调用action(t)更改为await func(t)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47205978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档