2013-02-03 106 views
0

我正在为我的问题寻找一个有效的解决方案。我正在使用VS 2010.我想从wcf服务方法执行一系列操作,并将每个操作状态发回到调用客户端。我已经设置回调合同和使用双工通道wcf,我可以连接到wcf。当我开始长时间运行的操作时,有时它会触发回呼,有时不会。我不知道为什么。以下是我所关注的方法。C#Backgroundworker新问题

在WCF服务方法,

public void Start() 
    { 
     List<Employee> empLists = GetEmpData(); // geting lots of employee objects 
     foreach(Employee emp in empLists)  // maybe 1000 records 
     { 
      StartlongRunning(emp); 
     } 
    } 

private void StartlongRunning(Employee emp) 
{ 
    // here i am creating a new background worker... 
    // Here i am registering for RunWorkerCompleted, DoWork, ReportProgress events... 
    bgw.RunWorkerAsync(emp) 
} 

void bgw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Employee emp = (Employee)e.Argument; 
    using (ClassA p = new ClassA(emp.ID)) // this class is from another dll. 
    { 
     e.Result = p.StartProcess(emp.Code); 
    } 
} 

void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // This is not calling properly. 
    // Sometimes this method is working...most of the time it is not working.. 
    // here i am unregistering the registerd DoWork, RunWorkerCompleted events... 
    // calling bgw.Dispose(); // i tried without this also;...but no use... 
    // from here I am firing the callback to client... 
} 

这里是StartProcess方法的实现。

public string StartProcess(string empcode) 
{ 
    // call to another method1() // here saving to DB frequently. works fine 
    // call to another method2() // here also saving to DB frequently. works fine 
    // call to someother method3() // here also some DB insert frequently. fine 
    // call to Method4() // here also some DB insert. 
          // this method is not calling frequently.. 
          // sometimes it is calling but most of times not..why ??? 
    return value; 
} 

private void SaveToDB(args1, args2...) 
{ 
    DatabaseHelper.Save(args1, args2.....); // this static class is from another dll 
    // only DB operation in this static class.. 
} 

该静态类的实现如下所示。

using (SqlConnection conn = new SqlConnection(DBConnection)) 
{ 
    conn.open; 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
     ...adding parameters 
     cmd.ExecuteNonQuery(); 
     } 
     conn.close(); 
} 

如果StartProcess回报,那么后台工作人员将执行RunWorker方法。 但它没有发生。这里有什么问题?

我为每个后台工作者创建每个ClassA对象。 一旦ClassA的对象完成,它将被处置。

但我不知道为什么StartProcess没有正确返回呼叫。

在我的实现中,背景工作者之间是否存在重叠的对象ClassA

+0

我不确定这是否是您的问题,但它看起来像您可能试图同时打开超过1000个SqlConnections。数据库服务器配置问题一次可以获得多少个连接。如果您的数据库只提供三个连接,则几乎所有的后台线程都处于等待状态,直到使用这三个连接的操作为止。 –

+0

@PhillipScottGivens。谢谢回复。但它有时可以正常工作。当我运行应用程序时,我通过执行每个表的计数来检查数据库。在每次频繁点击运行按钮时,在sql查询窗口中,方法1,2和3的表的计数都在增加。但方法4的表未更新。它显示计数为0.但是当我运行应用程序时,1或2次,所有4个表都显示计数,这意味着一切工作正常。我不知道这里有什么问题? –

回答

1

我认为问题在于你在循环中调用RunWorkerAsync而不检查它是否不忙。 您应该使用列表作为参数调用RunWorkerAsync,而不是尝试在不同线程中启动所有工作。

我会做这样的事情:

public void Start() 
{ 
    List<Employee> empLists = GetEmpData(); // geting lots of employee objects 
    StartlongRunning(empLists); 
} 

并相应地改变bgw_DoWork。

如果您需要查看进度,则可以为每个员工对象调用ReportProgress。

+0

我认为这是一个好主意,让我检查一下。但顺序执行会影响性能? –

+0

是的,它工作正常。但是执行每个项目非常耗时。我正在寻找并行的东西。 –

+0

我以为你正在更新一个数据库,使它并行不会更快,因为数据库将无论如何使它顺序,因为它在更新时锁定表和索引。 – Casperah

0

如果您想在同一时间创建应用程序以与多个backgroundWorkers一起工作,则应为每个正在执行的操作初始化新的backgroundWorker对象。这将解决问题。

+0

Vasic。谢谢回复。但是我为每个操作创建新的bgw。你能指定更多你的想法吗? –

+0

正如我所见。您正在运行相同的backgroundWorker。你可以创建BackgroundWorker bw = new BackgroundWorker();实例或数组与每个调用。你可以从代码中添加事件,但不是来自设计者。 worker.DoWork + = new DoWorkEventHandler(update.DoUpdate); –