c# - What is the best way to end a task to prevent run-away -
i have created function below wait tasks complete or raise exception when cancellation or time-out occurs.
public static async task whenall( ienumerable<task> tasks, cancellationtoken cancellationtoken, int millisecondstimeout) { task timeouttask = task.delay(millisecondstimeout, cancellationtoken); task completedtask = await task.whenany( task.whenall(tasks), timeouttask ); if (completedtask == timeouttask) { throw new timeoutexception(); } }
if tasks
finished before long time-out (i.e. millisecondstimeout
= 60,000), timeouttask
staying around until 60 seconds has elapsed after function returns? if yes, best way fix runaway problem?
yes, timeouttask
hang around until timeout on (or cancellationtoken
canceled).
you can fix passing in different cancellationtoken
new cancellationtokensource
create using cancellationtokensource.createlinkedtokensource
, cancelling @ end. should await completed task, otherwise aren't observing exceptions (or cancellations):
public static async task whenall( ienumerable<task> tasks, cancellationtoken cancellationtoken, int millisecondstimeout) { var cancellationtokensource = cancellationtokensource.createlinkedtokensource(cancellationtoken); var timeouttask = task.delay(millisecondstimeout, cancellationtokensource.token); var completedtask = await task.whenany(task.whenall(tasks), timeouttask); if (completedtask == timeouttask) { throw new timeoutexception(); } cancellationtokensource.cancel(); await completedtask; }
however, think there's simpler way achieve want, if don't need distinguish between timeoutexception
, taskcancelledexception
. add continuation cancelled when cancellationtoken
cancelled or when timeout over:
public static task whenall( ienumerable<task> tasks, cancellationtoken cancellationtoken, int millisecondstimeout) { var cancellationtokensource = cancellationtokensource.createlinkedtokensource(cancellationtoken); cancellationtokensource.cancelafter(millisecondstimeout); return task.whenall(tasks).continuewith( _ => _.getawaiter().getresult(), cancellationtokensource.token, taskcontinuationoptions.executesynchronously, taskscheduler.default); }
Comments
Post a Comment