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

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

问题描述

我有一个自定义框架,宿主应用程序在其中运行事件循环,并将来宾应用程序加载到单独的应用程序域中.来宾应用程序具有通过提供的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:

在另一个AppDomain

我通过在调用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,则可以在等待后在该线程上继续.

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

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

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