问题
I have a custom framework where a host application runs an event loop and loads a guest application into a separate app-domain. The guest application has means to take advantage of the event loop via a provided API. I want to make the guest application be able to automatically propagate all continuations onto the event loop much like it's done in .NET GUI applications and the UI thread. Therefore, I create a custom synchronization context which is able to do that.
But the problem is I can't start using this new context. Whenever I try to set it up, it's reset back to null
in the next callback across the app-domain boundary.
Here goes a quick code snippet to illustrate the problem:
using System;
using System.Threading;
class Test : MarshalByRefObject {
public void Do() {
Console.WriteLine("TID: {0}, SC: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current != null ? "present" : "absent");
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
}
static class Program {
static void Main() {
try {
var domain = AppDomain.CreateDomain("Other Domain");
var obj = (Test)domain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName);
obj.Do();
obj.Do();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
}
Output:
TID: 1, SC: absent
TID: 1, SC: absent
There is also this SynchronizationContext.SetThreadStaticContext
method which could potentially solve the above problem if it was available on desktop.
Of course, there is always a way to explicitly set a context in each callback before doing any other work. But that seems a little lousy. Besides that, I can't see an elegant way to solve this chicken-egg problem. It works as expected on Mono by the way.
回答1:
You are probably no longer interested in this but your problem is probably simular to mine:
No SynchronizationContext when calling Await in a another AppDomain
I solved this by grabbing the current dispatcher before calling await. (In my case way before)
protected async void RefreshData()
{
var dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
_data = await LoadAsync(_taskId);
dispatcher.Invoke(() => OnDataChanged());
}
So if I enter RefereshData on the UI thread, I can continue on that thread after the await.
来源:https://stackoverflow.com/questions/28758201/cant-set-synchronization-context-when-using-appdomains