c# - Why Task.WhenAll(taskList) doesn't work? -
if task in foreach
isn't async
, , make ping.send
instead of ping.sendpingasync
task.whenall(tasklist)
work.
list<task> tasklist = new list<task>(); foreach (var host in hostarray) { var ahost = host; task task = new task(async ()=> { ping ping = new ping(); pingresult pingres = new pingresult { hostnameoraddress = ahost }; (int = 0; < _pingcount; i++) { try { pingreply reply = await ping.sendpingasync(ahost,1000); if (reply.status == ipstatus.success) pingres.roundtriptimes.add(reply.roundtriptime); } catch { // ignored } } dispatcher.invoke(() => { _pingresultlist.add(pingres); }); }); tasklist.add(task); task.start(); } await task.whenall(tasklist); //never wait.
don't use task's constructor. doesn't support asynchronous lambda. instead use task.run
.
your code @ moment waits till sendpingasync
called in tasks, not whole asynchronous method finish. because first await point hit, asynchronous methods return.
your async lambda compiles task(action)
means gets compiled async void method. since there no easy way wait async void methods, task class constructor doesn't support it. conversely task.run
supports asynchronous method via task.run(func<task>)
overload. since returns task
, run method can wait completion.
not asynchronous methods, prefer task.run
or task.factory.startnew
(if need more control). there no reason 1 use task
constructor.
if decide use startnew
asynchronous methods, you'll have call task.unwrap , wait task returned it. when you're using task.run, free.
Comments
Post a Comment