使用应用程序域时无法设置同步上下文 [英] Can't set synchronization context when using appdomains

查看:21
本文介绍了使用应用程序域时无法设置同步上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义框架,其中主机应用程序运行事件循环并将来宾应用程序加载到单独的应用程序域中.来宾应用程序可以通过提供的 API 来利用事件循环.我想让来宾应用程序能够自动将所有延续传播到事件循环中,就像在 .NET GUI 应用程序和 UI 线程中所做的那样.因此,我创建了一个能够做到这一点的自定义同步上下文.

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.

但问题是我无法开始使用这个新上下文.每当我尝试设置它时,它都会在下一个跨应用域边界的回调中重置回 null.

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());
        }
    }
}

输出:

TID: 1, SC: absent
TID: 1, SC: absent

还有这个 SynchronizationContext.SetThreadStaticContext 方法,如果它在桌面上可用,它可以潜在地解决上述问题.

There is also this SynchronizationContext.SetThreadStaticContext method which could potentially solve the above problem if it was available on desktop.

当然,在执行任何其他工作之前,总是有一种方法可以在每个回调中显式设置上下文.但这似乎有点糟糕.除此之外,我看不到解决这个鸡蛋问题的优雅方法.顺便说一下,它在 Mono 上按预期工作.

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.

推荐答案

您可能不再对此感兴趣,但您的问题可能与我的类似:

You are probably no longer interested in this but your problem is probably simular to mine:

在调用 Await 时没有 SynchronizationContext另一个应用程序域

我通过在调用 await 之前获取当前调度程序解决了这个问题.(以我之前的情况为例)

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());
}

所以如果我在 UI 线程上输入 RefereshData,我可以在 await 之后继续该线程.

So if I enter RefereshData on the UI thread, I can continue on that thread after the await.

这篇关于使用应用程序域时无法设置同步上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆