我试图了解C#5中async-await的用法。如果我有2种方法启动的作业,是否有最佳方法等待C#5 +中的作业完成?我已经完成了下面的示例,但是除了带有async关键字的免费文档之外,我看不到异步等待键将带来什么。
我举了下面的例子,我想“完成!”最后打印。但是事实并非如此。我错过了什么 ?如何使异步方法等待所有作业完成?在这里使用async-await有一点吗?我可以在这里使用非异步方法执行Task.WaitAll。我真的不明白,如果您想等待,异步会带来什么。
class Program
{
static void Main(string[] args)
{
var fooWorker = new FooWorker();
var barWorker = new BarWorker();
var test = new Class1(fooWorker, barWorker);
test.SomeWork();
Console.ReadLine();
}
}
public class Foo
{
public Foo(string bar) => Bar = bar;
public string Bar { get; }
}
public class Class1
{
private IEnumerable<Foo> _foos;
private readonly FooWorker _fooWorker;
private readonly BarWorker _barWorker;
public Class1(FooWorker fooWorker, BarWorker barWorker)
{
_fooWorker = fooWorker;
_barWorker = barWorker;
}
public void SomeWork()
{
_foos = ProduceManyFoo();
MoreWork();
Console.WriteLine("FINISHED !");
}
private async void MoreWork()
{
if (_foos == null || !_foos.Any()) return;
var fooList = _foos.ToList();
Task fooWorkingTask = _fooWorker.Work(fooList);
Task barWorkingTask = _barWorker.Work(fooList);
await Task.WhenAll(fooWorkingTask, barWorkingTask);
}
private IEnumerable<Foo> ProduceManyFoo()
{
int i = 0;
if (++i < 100) yield return new Foo(DateTime.Now.ToString(CultureInfo.InvariantCulture));
}
}
public abstract class AWorker
{
protected virtual void DoStuff(IEnumerable<Foo> foos)
{
foreach (var foo in foos)
{
Console.WriteLine(foo.Bar);
}
}
public Task Work(IEnumerable<Foo> foos) => Task.Run(() => DoStuff(foos));
}
public class FooWorker : AWorker { }
public class BarWorker : AWorker { }
答案 0 :(得分:0)
在线程继续运行的同时,您正在解雇任务并忘记了它们。这样就可以解决。
主要:
static async Task Main(string[] args)
{
var fooWorker = new FooWorker();
var barWorker = new BarWorker();
var test = new Class1(fooWorker, barWorker);
await test.SomeWork();
Console.ReadLine();
}
一些工作:
public async Task SomeWork()
{
_foos = ProduceManyFoo();
await MoreWork();
Console.WriteLine("FINISHED !");
}
MoreWork签名更改:
private async Task MoreWork()
正在使用async void
来消除明显的代码异味,这应该有助于弄清楚问题。除非有要求,否则应始终避免。
使用async
和await
时,通常需要将await
调用链接到顶层(在这种情况下为Main
)。
await
是非阻塞的,因此任何调用async
方法的人都应该真正关心返回的Task
。