ホスト アプリケーションがイベント ループを実行し、ゲスト アプリケーションを別のアプリケーション ドメインにロードするカスタム フレームワークがあります。ゲスト アプリケーションには、提供された API を介してイベント ループを利用する手段があります。.NET GUI アプリケーションや UI スレッドで行われるように、ゲスト アプリケーションがすべての継続をイベント ループに自動的に伝達できるようにしたいと考えています。したがって、それが可能なカスタム同期コンテキストを作成します。
しかし問題は、この新しいコンテキストを使い始めることができないことです。設定しようとすると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では期待どおりに動作します。