2013-02-10 29 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