SubscribeOn
ブロックを防ぐために別のスレッドを使用するRx サブスクリプションがあります。ただし、リソース管理の問題により、そのサブスクリプションの破棄をブロックしたいと考えています。コンソール アプリまたは winforms アプリのいずれかのコンテキスト内でこれを達成する方法を理解できませんでした (両方のユース ケースがあります)。以下は、私がやっていることをシミュレートする縮小ケースの作業コードです:
internal class Program
{
private static void Log(string msg)
{
Console.WriteLine("[{0}] " + msg, Thread.CurrentThread.ManagedThreadId.ToString());
}
private static void Main(string[] args)
{
var foo = Observable.Create<long>(obs =>
{
Log("Subscribing starting.. this will take a few seconds..");
Thread.Sleep(TimeSpan.FromSeconds(2));
var sub =
Observable.Interval(TimeSpan.FromSeconds(1))
.Do(_ => Log("I am polling..."))
.Subscribe(obs);
return Disposable.Create(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(3));
sub.Dispose();
Log("Disposing is really done now!");
});
});
Log("I am subscribing..");
var disp = foo.SubscribeOn(NewThreadScheduler.Default).Subscribe(i => Log("Processing " + i.ToString()));
Log("I have returned from subscribing...");
// SC.Current is null in a ConsoleApp :/ Can I get a SC that uses my current thread?
//var dispSynced = new ContextDisposable(SynchronizationContext.Current, disp);
Thread.Sleep(TimeSpan.FromSeconds(5));
Log("I'm going to dispose...");
//dispSynced.Dispose();
disp.Dispose();
Log("Disposed has returned...");
Console.ReadKey();
}
}
上記を実行すると、次のようになります。
[10] I am subscribing..
[10] I have returned from subscribing...
[11] Subscribing starting.. this will take a few seconds..
[6] I am polling...
[6] Processing 0
[6] I am polling...
[6] Processing 1
[10] I'm going to dispose...
[10] Disposed has returned...
[13] I am polling...
[6] I am polling...
[13] I am polling...
[14] Disposing is really done now!
したがって、私がやろうとしている[10] Disposed has returned...
のは、Dispose 呼び出しがブロックされていることを示す最後の行を出力することだけです。
Rx に同梱されている は私の使用例には理想的ですが、現在のスレッドを表すContextDisposable
を取得する方法がわかりません。私がやりたいことを行うためにSynchronizationContext
使用できる方法はありますか、それともまったく異なるアプローチが必要ですか?ContextDisposable