我有一个WPF应用程序,它使用System.Threading.Tasks在后台调用WCF服务.我正在使用Task.ContinueWith将服务调用的结果返回给WPF UI线程.我的问题是,虽然继续运行确实在UI线程上运行,但是它确实是SynchronizationContext.Current为null.我可以运行相同的代码,在初始Task中注释掉WCF调用,并且继续在UI线程上,并按预期使用DispatcherSynchronizationContext.
WCF代理使用ChannelFactory生成,并使用wsHttpBinding.没有回调合约.相关代码如下所示:
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 }
Run Code Online (Sandbox Code Playgroud)
如果我按原样运行此代码,则在正确的线程上调用ServiceContinuation(使用ManagedThreadID验证),但SynchronizationContext.Current为null.如果我注释掉进行服务调用的单行(result = service.TheServiceMethod();),则使用DispatcherSynchronizationContext正确调用ServiceContinuation.
一个注意事项 - SynchronizationContext不会永久丢失 - 如果我再次单击该按钮,则按钮单击处理程序确实具有正确的SynchronizationContext.
我已经捕获了两个案例的堆栈跟踪; …