我有一個IEnumerable序列,它包含一些阻塞網絡操作(在下面的示例代碼中用一些簡單的yield代替)。我正在使用Reactive Extensions將通過網絡傳輸的數據流轉換爲可觀察的序列。跨線程編組異常(反應式擴展)
我正在尋找一種方法將異常封送到主線程,以便未處理的異常不會導致我的應用程序終止。我不能在IEnumerable線程上放置try/catch塊,因爲編譯器不允許try/catch語句中的yield return語句。
using System;
using System.Collections.Generic;
using System.Concurrency;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Main thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
var observable = TestEnumerable().ToObservable(Scheduler.NewThread); //Needs to be on a new thread because it contains long-running blocking operations
// Use subject because we need many subscriptions to a single data source
var subject = new Subject<int>();
subject.Subscribe(x => Console.WriteLine("Subscriber1: " + x + " on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId),
x => Console.WriteLine("Subscriber1 ERROR: " + x+ " on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId),
() => Console.WriteLine("Subscriber1 Finished"+ " on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId));
subject.Subscribe(x => Console.WriteLine("Subscriber2: " + x + " on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId),
x => Console.WriteLine("Subscriber2 ERROR: " + x+ " on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId),
() => Console.WriteLine("Subscriber2 Finished"+ " on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId));
Console.WriteLine("Press key to start receiving data");
Console.ReadKey();
var sub = observable.Subscribe(subject);
Console.WriteLine("Press key to exit");
Console.ReadKey();
sub.Dispose();
}
catch (Exception ex)
{
Console.WriteLine("Caught exception on main thread");
}
}
public static IEnumerable<int> TestEnumerable()
{
while (true)
{
yield return 1;
Thread.Sleep(200);
yield return 2;
Thread.Sleep(200);
yield return 3;
Thread.Sleep(200);
throw new InvalidOperationException();
}
}
}
}
是你的使用場景_actually_控制檯應用程序,還是使用UI的東西? – 2011-02-28 20:14:36
此外,您是否考慮過使用'IConnectableObservable'(通過'Publish')而不是'Subject'來共享可觀察的? – 2011-02-28 21:11:20
使用場景是一個控制檯應用程序。我沒有聽說過IConnectableObservable,我會做一些研究。感謝您的幫助......會給您的解決方案一個嘗試。 – Oenotria 2011-02-28 21:29:17