c# - How to substitute synchronization context / task scheduler to another one inside TaskCompletionSource.Task for ConfigureAwait(false)? -
this question has answer here:
assume created library containing such method:
task mylibrarymethodasync() { var taskcompletionsource = new taskcompletionsource<object>(); action myworkitem = () => { // simulate work. // actual work items depend on input params. thread.sleep(timespan.fromseconds(1)); taskcompletionsource.setresult(null); }; // next 2 lines simplification demonstration. // not have access workerthread - created // , managed me lib. // can - post short work items it. var workerthread = new thread(new threadstart(myworkitem)); workerthread.start(); return taskcompletionsource.task; }
any user of lib can call mylibrarymethodasync
this
await mylibrarymethodasync().configureawait(false); verylongrunningmethod();
void verylongrunningmethod() { thread.sleep(timespan.fromhours(1)); }
and here problem comes – verylongrunningmethod
executed inside taskcompletionsource.setresult(null)
call , block workerthread
long period of time, not desired behavior because workerthread
intended run small portions of code (work items).
how substitute context / scheduler thread pool inside returned task making await x.configureawait(false)
continue on thread pool, not on workerthread
?
the current solution found is
task mylibrarymethodasync() { // ... return taskcompletionsource.task .continuewith(x => x.result, taskscheduler.default); }
however, not due overhead creates. may more elegant solution exists?
as of .net 4.6 there option in taskcreationoptions
called runcontinuationsasynchronously
, want, ensures continuations run asynchronously, rather run synchronously when setting result. taskcompletionsource
has optional taskcreationoption
parameter in constructor provide option.
if you're using earlier version of .net you'll need less efficient hack, such adding continuation, showed, or explicitly setting result in thread pool thread, rather through callback action.
Comments
Post a Comment