我有一个自定义框架,其中主机应用程序运行事件循环并将来宾应用程序加载到单独的应用程序域中。来宾应用程序具有通过提供的API利用事件循环的方法。我想让guest应用程序能够自动将所有continuation传播到事件循环,就像在.NET GUI应用程序和UI线程中完成的那样。因此,我创建了一个能够做到这一点的自定义同步上下文。
但问题是我无法开始使用这个新的上下文。每当我尝试设置它时,它会在app-domain边界的下一个回调中重置为null
。
这里有一个快速的代码片段来说明问题:
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());
}
}
}
输出:
TID: 1, SC: absent
TID: 1, SC: absent
还有这种SynchronizationContext.SetThreadStaticContext
方法,如果可以在桌面上使用,它可以解决上述问题。
当然,在执行任何其他工作之前,始终有一种方法可以在 每个 回调中明确设置上下文。但这似乎有点糟糕。除此之外,我看不出一种解决鸡蛋问题的优雅方法。顺便说一句,它在Mono上按预期工作。
答案 0 :(得分:0)
您可能不再对此感兴趣,但您的问题可能与我的问题相似:
No SynchronizationContext when calling Await in a another AppDomain
我通过在调用await之前抓住当前的调度程序来解决这个问题。 (以我的方式来说)
protected async void RefreshData()
{
var dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
_data = await LoadAsync(_taskId);
dispatcher.Invoke(() => OnDataChanged());
}
因此,如果我在UI线程上输入RefereshData,我可以在等待之后继续该线程。