2013-02-10 26 views
1

我一直在尋找解決方案來解決我在RX上看到的問題。爲什麼從Reactive ToObservable中使用的方法沒有返回?

我有一個對象列表:List<Employee>,每個員工都有一個ID和代碼。在另一個dll中有一個類,它接收每個員工的id和代碼號,並執行涉及多個db插入的長時間運行的處理。這個數據庫插入是在另一個DLL的靜態類。

我的問題是我使用的RX查詢有時只是工作而不是大部分時間。這意味着代碼中沒有錯誤。如果運行代碼10次,2次正常工作,8次失敗。我正在使用.NET框架的v4.0。

IObservable<string> RunProcess(Employee emp) 
    {   
     using (AnotherDLLClass p = new AnotherDLLClass(emp.id)) 
     { 
      return Observable.Start(() => p.StartLongRun(emp.Code), Scheduler.ThreadPool); 
     }       
    } 

此employeedatas列表可能包含1000或2000條記錄。

EmployeeDatas.ToObservable().Select(x => RunProcess(x).Select(y => new { edata = x, retval = y })) 
        .Merge(10) 
        .ObserveOn(Scheduler.CurrentThread) 
        .Subscribe(x => 
        { 
         SendReportStatus(x.retval.Item1, x.retval);       
        }); 

另一個dll中的StartLongRun()方法具有以下結構。

public string StartLongRun(string code) 
    { 
    Method1(); // this method has a loop and each loop inserts data to db. 
       // each loop calls DBHelper.Save() method to insert data to db. 
       // sql con.opens and closes for each insert. 

    Method2(); // doing exactly the same like Method1; 

    return statusreport; // This return is not happening ???? 

    } 

運行的應用程序後,當我檢查數據庫,該值被插入到數據庫 正常。每當我檢查表的數量時,數據都會正確保存 並且每秒鐘的計數都在增加。

但爲什麼該方法沒有正確返回。 AnotherDLLClass實現了IDisposable。當我將折點放在返回零件代碼上時,它不會觸及那裏。

當EmployeeDatas只有一個項目時,它會在那裏。第一天,當我實現代碼時,它可以正常工作1000個項目。整天我工作了相同的代碼,它在1000個項目中工作正常。

但第二天,當我運行該應用程序,數據正確插入,但它沒有返回該調用。我不明白這個奇怪的行爲。

請指出這一點,並指導我。

沒有人回答這個奇怪的行爲的任何解決方案。我在這裏有任何錯誤嗎?請指導我。

回答

0
using (AnotherDLLClass p = new AnotherDLLClass(emp.id)) 
{ 
    return Observable.Start(() => p.StartLongRun(emp.Code), Scheduler.ThreadPool); 
} 

在上面的代碼,你的using子句中實例化p。然後,您將在異步調用的lambda表達式中使用p。它看起來像比賽條件。如果() => p.StartLongRun將被快速執行,那麼沒有例外。但是在}using之後,p被處置並且內部lambda表達式將失敗。

+0

感謝您的回覆。但是如果我使用不使用子句,它是一樣的。它不會回電話。爲什麼我使用的是,AnotherDLLClass內部有很多對象,如另一個Web服務代理對象,ADO對象等。因此,對於每次調用,它應該處理另一個DLLClass使用的所有資源。這就是爲什麼我使用子句。即使我創建anotherDLLClass的實例並調用p.StartLongRun()方法,結果也沒有變化。你有什麼想法嗎? – 2013-02-16 10:28:08

+0

我在'Scheduler.ThreadPool'中看到的另一個麻煩。根據MSDN _This調度程序是短期運行操作的理想選擇._將其替換爲'Scheduler.NewThread'。根據MSDN _This調度程序是長時間運行操作的理想選擇._ – 2013-02-16 13:15:02

+0

嗨,我也試過用NewThread很久很久了。它比ThreadPool慢。但它不會返回。如果我運行1個員工對象,我的LongRunning方法將花費最多15-20秒。這就是爲什麼我使用ThreadPool,而且第一次運行時速度非常快。但我不知道發生了什麼事。如果我把StartLongRun()方法的最後一個return語句的中斷點放在那裏,它將永遠不會到達那裏。 – 2013-02-16 14:21:14