/// <summary> /// Blows up because trying to access GUI from wrong context. /// </summary> /// <param name="parameter"></param> public async void Execute(object parameter) { TheViewModel vm = parameter as TheViewModel; vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; //Switching to default context here. string msg = await CallSomethingAsync(vm).ConfigureAwait(continueOnCapturedContext: false); //Still on default context, no access to GUI thread. Boom. vm.UpdateDescription(msg); }
/// <summary> /// Works because we never switch contexts /// </summary> /// <param name="parameter"></param> public async void Execute(object parameter) { TheViewModel vm = parameter as TheViewModel; vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; //Remains context aware string msg = await CallSomethingAsync(vm); vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; vm.UpdateDescription(msg); }
/// <summary> /// Deadlocks /// </summary> /// <param name="parameter"></param> public void Execute(object parameter) { TheViewModel vm = parameter as TheViewModel; vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; //Blocks while CallSomethingAsync runs. CallSomethingAsync //cannot resume on the context because .Result is blocking. var msg = CallSomethingAsync(vm); vm.UpdateDescription(msg.Result); }
/// <summary> /// Deadlocks /// </summary> /// <param name="parameter"></param> public void Execute(object parameter) { TheViewModel vm = parameter as TheViewModel; vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; //Blocks while CallSomethingAsync runs. string msg = CallSomethingAsync(vm).Result; vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; vm.UpdateDescription(msg); }
/// <summary> /// Work is done on default context but is resumed on the /// captured context. /// </summary> /// <param name="parameter"></param> public async void Execute(object parameter) { TheViewModel vm = parameter as TheViewModel; vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; //No ConfigureAwait False here! The work in that method DOES //operate on a different conext but execution will resume //on the original context so we can access the GUI thread. string msg = await CallSomethingAsync(vm); vm.UpdateDescription(msg); vm.CurrentThreadID = Thread.CurrentThread.ManagedThreadId; }