2013-04-04 155 views
0

我正在读文件到内存中,然后尝试为每一行执行web服务调用。我想要做的是这样的: 1.阅读文件 2.创建新线程 - >执行第1行的Web服务调用 3.创建新线程 - >执行第2行的Web服务调用 4 。更新“状态”框,结果来自服务呼叫1或2,其中有一个首先得到回应backgroundworker只触发一次

换句话说,我试图对文件中的每一行执行多个Web服务调用,并更新状态框当他们回来时。我不想打一个电话,然后在第一个电话返回后开始第二个电话。

编辑:忘了提,在调试时,我发现只有一个呼叫作出,因为readFileBackgroundWorker.IsBusy通过foreach循环去时是true,但如果我删除,然后我得到一个错误This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.

读取文件在:

private void uxReadFileButton_Click(object sender, EventArgs e) 
    { 
     uxFileStatusLabel.Text = String.Empty; 
     this.uxReadFileButton.Enabled = false; 
     this.uxCancelReadingFileButton.Enabled = true; 
     var clientList = ReadFile(uxFileNameBox.Text); 

     foreach (var client in clientList) 
     { 
      if (readFileBackgroundWorker.IsBusy != true) 
      { 
       readFileBackgroundWorker.RunWorkerAsync(client); 
      } 
     } 
    } 

private void readFileBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var worker = (BackgroundWorker)sender; 
     ProcessClient((ClientObject)e.Argument, worker, e); 
    } 

private void ProcessClient(ClientObject client, BackgroundWorker worker, DoWorkEventArgs e) 
    { 
     try 
     { 
      client.FileClientDischarge(SystemCode, UserName, Password); 
      int percent = (int)(Math.Ceiling(((double)(client.RecordNumber + 1)/121) * 100)); 
      worker.ReportProgress(percent, client); 
     } 
     catch (Exception ex) 
     { 
      worker.CancelAsync(); 
     } 
     e.Result = client.RecordNumber; 
    } 
+0

我不知道我的理解。很简单,把一个Web服务调用已经是异步的。因此,在后台工作者上,一次只读取一行文件,使用内联代理附加到Web服务回调事件,并在该代理内部调用报告进度方法。如果它在该后台工作者中的代码超过15行,那么可能太多了,如果这是有道理的。您不需要为每一行添加一个新线程 - Web服务调用已经是异步的。 – 2013-04-04 12:27:35

回答

1

您的后台工作人员只运行一次的原因是当您第二次拨打RunWorkerAsync()时,它很忙。您应该为循环的每次迭代创建一个后台工作器。

private void uxReadFileButton_Click(object sender, EventArgs e) 
{ 
    uxFileStatusLabel.Text = String.Empty; 
    this.uxReadFileButton.Enabled = false; 
    this.uxCancelReadingFileButton.Enabled = true; 
    var clientList = ReadFile(uxFileNameBox.Text); 
    BackGroundWorker bgw; 

    foreach (var client in clientList) 
    { 
     bgw = new BackgroundWorker(); 
     bgw.DoWork += readFileBackgroundWorker_DoWork; 
     //bgw.RunWorkerCompleted += 

     bgw.RunWorkerAsync(client); 
    } 
} 

private void readFileBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var worker = (BackgroundWorker)sender; 
    ProcessClient((ClientObject)e.Argument, worker, e); 
} 

private void ProcessClient(ClientObject client, BackgroundWorker worker, DoWorkEventArgs e) 
{ 
    try 
    { 
     client.FileClientDischarge(SystemCode, UserName, Password); 
     int percent = (int)(Math.Ceiling(((double)(client.RecordNumber + 1)/121) * 100)); 
     worker.ReportProgress(percent, client); 
    } 
    catch (Exception ex) 
    { 
     worker.CancelAsync(); 
    } 
    e.Result = client.RecordNumber; 
} 

请签上Cancelling a BackGroundWorker DoWork

+0

这工作......谢谢你是如此详细,并指出'BackgroundWorker取消' – SOfanatic 2013-04-05 12:43:48

0

你应该尝试使用多线程作为foreach循环在你的工作者完成工作之前完成。

0

这太问题,你可以使用的东西开始多backgroundworkers做你的Web服务调用并行像

foreach (var client in clientList) 
    { 
     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
     worker.RunWorkerAsync(i); 
    }