2014-03-04 38 views
0

我對此很新,所以請對我輕鬆點。我基本上是用一個按鈕開始一個後臺進程。在同一個按鈕上,我想捕獲響應。我知道有一個runworkercompleted方法,但是我希望點擊按鈕來接收響應。在這個例子中,我創建了一個任務用一些文本填充的字典。想要啓動線程的按鈕能夠從字典中讀取值。來自後臺工作人員的c#捕獲響應

下面的代碼:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 

namespace background_worker 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     Dictionary<Guid , string> _taskdictionary = new Dictionary<Guid, string>(); 


     private void button1_Click(object sender, EventArgs e) 
     { 
      //create new task id (guid) and start task 
      Guid taskID = Guid.NewGuid(); 
      backgroundWorker1.RunWorkerAsync(taskID); 

      //how do i know when i can grab the result of the threaded job? 
      //i know it will be in dictionary but how do i get hold of it 
      if (_taskdictionary.ContainsKey(taskID)) 
       this.Text = _taskdictionary[taskID]; 
     } 


     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      //task will be added to taskdictionary with result 

      Guid taskid = (Guid)e.Argument; 
      if (!_taskdictionary.ContainsKey(taskid)) 
       _taskdictionary.Add(taskid, "this is the result"); 

      #region 
      //task will log to file 
      string lines = "this is the result"; 
      System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\result" + taskid.ToString() + ".txt"); 
      file.WriteLine(lines); 
      file.Close(); 
      #endregion 

      e.Result = "complete"; 
     } 

     private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      //MessageBox.Show((string)e.Result); 

     } 
    } 
} 
+0

問題不清楚,請說清楚。以及不使用「TaskParalellLibrary」的原因? –

+0

不清楚?我基本上想要按鈕來觸發後臺線程,並等待DoWork的結果。 – user2143783

+0

使用BackgroundWorker的要點是在不等待代碼結束的情況下異步運行一些代碼。如果您等待按鈕單擊事件返回BackgroundWorker,則基本上會同步運行它,使BackgroundWorker過時。你能澄清你爲什麼要使用BackgroundWorker以及爲什麼要在click事件處理程序中使用返回嗎?如果您的示例類似於您的真實世界代碼,那麼您還可以在RunWorkerCompleted中分配按鈕文本(如果這會產生錯誤,您可能需要使用Invoke)。 – Markus

回答

1

您可以使用C#5.0的異步功能來處理這種情況下,甚至不需要使用一個BackgroundWorker:

private async void button1_Click(object sender, EventArgs e) 
{ 
    var result = await Task.Run(() => ComputeResult()); 
    DoStuffWithResult(result); 
} 

另一種選擇,如果它有很重要點擊按鈕編寫的代碼是通過匿名方法在按鈕點擊中附加BGW的事件處理程序:

private void button1_Click(object sender, EventArgs e) 
{ 
    var worker = new BackgroundWorker(); 
    worker.DoWork += ComputeResult; 
    worker.RunWorkerCompleted += (s, args) => 
    { 
     DoStuffWithResult(args.Result); 
    }; 
    worker.RunWorkerAsync(); 
} 

如果你不想這樣做,那麼答案就是你不能。這裏的要點是,按鈕點擊需要完成工作之前完成,以便它可以返回到它的調用者(消息循環),以便它可以繼續處理消息,以防止UI凍結。