WPF + Tasks + WCF = No SynchronizationContext? -
i have wpf application using system.threading.tasks call wcf service in background. i'm using task.continuewith return results of service call wpf ui thread. issue that, although continuation run on ui thread, when synchronizationcontext.current null. can run same code, commenting out wcf call in initial task, , continuation on ui thread, dispatchersynchronizationcontext expected.
the wcf proxy generated using channelfactory, , uses wshttpbinding. there no callback contract. relevant code shown below:
private taskscheduler _uischeduler; public mainwindow() { initializecomponent(); _uischeduler = taskscheduler.fromcurrentsynchronizationcontext(); } private void button_click(object sender, routedeventargs e) { var servicetask = new task<int32>(servicecallwrapper, cancellationtoken.none, taskcreationoptions.none); var continuetask = servicetask.continuewith(result => servicecontinuation(result.result), cancellationtoken.none, taskcontinuationoptions.onlyonrantocompletion, _uischeduler); servicetask.start(); } private int32 servicecallwrapper() { int32 result = 0; var service = {elided - initializes service using channelfactory }; result = service.theservicemethod(); service.close(); return result; } private void servicecontinuation(int32 result) { elided }
if run code is, servicecontinuation called on correct thread (verified using managedthreadid), synchronizationcontext.current null. if comment out single line makes service call (result = service.theservicemethod();), servicecontinuation correctly called dispatchersynchronizationcontext.
one note - synchronizationcontext not permanently lost - if click on button again, button click handler have correct synchronizationcontext.
i've captured stack traces 2 cases; have few differences. i've left out of bits identical, , included top of stacks differ, plus few frames reference:
fails - calls wcf service
wpfcontinuationstest.mainwindow.servicecontinuation wpfcontinuationstest.mainwindow.<button_click>b__0 system.threading.tasks.task`1+<>c__displayclass17.<continuewith>b__16 system.threading.tasks.task.innerinvoke system.threading.tasks.task.execute system.threading.tasks.task.executioncontextcallback system.threading.executioncontext.runtrycode system.runtime.compilerservices.runtimehelpers.executecodewithguaranteedcleanup system.threading.executioncontext.runinternal system.threading.executioncontext.run system.threading.tasks.task.executewiththreadlocal system.threading.tasks.task.executeentry system.threading.tasks.synchronizationcontexttaskscheduler.postcallback
succeeds - no call wcf service
wpfcontinuationstest.mainwindow.servicecontinuation wpfcontinuationstest.mainwindow.<button_click>b__0 system.threading.tasks.task`1+<>c__displayclass17.<continuewith>b__16 system.threading.tasks.task.innerinvoke system.threading.tasks.task.execute system.threading.tasks.task.executioncontextcallback system.threading.executioncontext.run system.threading.tasks.task.executewiththreadlocal system.threading.tasks.task.executeentry system.threading.tasks.synchronizationcontexttaskscheduler.postcallback
does know why, when difference wcf client service call (with no callback contract), in 1 case continuation on main thread have synchronizationcontext, , in other case wouldn't?
according microsoft, known bug tpl:
http://social.msdn.microsoft.com/forums/en-us/wcf/thread/629d5524-c8db-466f-bc27-0ced11b441ba
Comments
Post a Comment