2013-12-13 47 views
0

我完全迷失了。我似乎沒有得到任何迴應。使用C的BackgroundWorker#

BackgroundWorker NewWorker; 

    public void StartBackgroundWorker() 
    { 
     BackgroundWorker NewWorker = new BackgroundWorker(); 
     NewWorker.DoWork += new DoWorkEventHandler(NewWorker_DoWork); 
     NewWorker.ProgressChanged += new ProgressChangedEventHandler(NewWorker_ProgressChanged); 
     NewWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(NewWorker_RunWorkerCompleted); 
     NewWorker.WorkerReportsProgress = true; 

     StartWorker(); 
    } 

    void NewWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     for (int i = 1; (i <= 10); i++) 
     { 
      if ((worker.CancellationPending == true)) 
      { 
       e.Cancel = true; 
       break; 
      } 
      else 
      { 
       ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select StatusCode from Win32_PingStatus where address = 'Metabox-PC'"); 
       ManagementObjectCollection objCollection = searcher.Get(); 
       foreach (ManagementObject Results in objCollection) 
       { 
        MessageBox.Show(Results.ToString()); 
       } 
       // Perform a time consuming operation and report progress. 
       System.Threading.Thread.Sleep(1); 
       worker.ReportProgress((i * 10)); 
      } 
     } 
    } 

    private void NewWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     MessageBox.Show("Finished"); 
    } 

沒有消息框出現,表示它已完成。 我錯過了什麼?

+2

'StartWorker'做什麼? –

+0

BackgroundWorker不是與UI不同的線程嗎? http://stackoverflow.com/questions/6755519/in-a-winforms-application-how-can-you-run-a-messagebox-from-a-background-worker# –

+0

@FrancisDucharme工人本身不在任何線程。它在幾個不同的線程中發射事件。 – Servy

回答

2

你永遠叫上你已經配置了BackgroundWorkerRunWorkerAsync

認爲你,因爲你調用StartWorker其中,(我相信)包含的代碼NewWorker.RunWorkerAsync();某處它,但是NewWorkerStartWorker內,指的是一個完全不同的BackgroundWorker你沒有配置做任何事。

您有一個實例字段NewWorkerStartBackgroundWorker的局部變量NewWorker,該實例字段是實例字段的陰影。

如果您確實需要後臺工作人員作爲實例字段,那麼請勿將其隱藏在StartBackgroundWorker中並在整個範圍內使用實例字段。如果你不需要它是一個實例字段(爲了記錄,這很可能並且不必要地將實例字段的變量提升爲messier程序),那麼你只需要開始在StartBackgroundWorker中創建的BackgroundWorkder。如果StartWorker確實有足夠的代碼需要使用另一種方法,那麼可能意味着它應該接受BackgroundWorker作爲參數,因此您可以傳入在StartBackgroundWorker中創建的工人。

2

問題是你永遠不會啓動你的NewWorker。這是因爲您的「全局」NewWorker始終爲空。

見固定碼:

NewWorker = new BackgroundWorker(); // this line is now fixed. 
    NewWorker.DoWork += new DoWorkEventHandler(NewWorker_DoWork); 
    NewWorker.ProgressChanged += new ProgressChangedEventHandler(NewWorker_ProgressChanged); 
    NewWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(NewWorker_RunWorkerCompleted); 
    NewWorker.WorkerReportsProgress = true; 

    StartWorker(); 
+0

爲了進一步說明,您在函數中定義了一個新的本地'NewWorker'變量。據推測,你打算使用班級中定義的全局變量。 – bland

1

爲什麼你需要讓背景工作者成爲一個領域?只要在構造函數和其他所有東西中使用它。在其事件中,您可以將該對象作爲BackgroundWorker進行投射。

public void StartBackgroundWorker() 
{ 
    BackgroundWorker NewWorker = new BackgroundWorker(); 
    NewWorker.DoWork += new DoWorkEventHandler(NewWorker_DoWork); 
    NewWorker.ProgressChanged += new ProgressChangedEventHandler(NewWorker_ProgressChanged); 
    NewWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(NewWorker_RunWorkerCompleted); 
    NewWorker.WorkerReportsProgress = true; 

    NewWorker.RunWorkerAsync(); 
} 
0

Francis是正確的...任何試圖在GUI線程以外的線程調用MessageBox都會被阻塞。你必須調用:

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { 
    MessageBox.Show("Hello World!"); 
})); 
+0

1)根本沒有回答這個問題2)是什麼讓你覺得他不想讓'Show'來阻止? – Servy

+0

@Servy 1)其實我是唯一回答他問題的人。我聲明試圖在GUI線程外部調用MessageBox將會阻塞,這就是爲什麼他完成的處理程序(它在主線程中發生)沒有被調用,因爲它阻塞了第一個MessageBox。 2)他很可能是,但這不是他的問題。他的問題是爲什麼他的完成處理程序沒有被調用。 –

+0

完成的處理程序未被調用,因爲具有完成的處理程序的BGW從未啓動。如果它*被啓動,那麼他會看到消息框,表示進度,儘管他說他不是,只是BGW會繼續工作,而一堆調用messagebox.show的東西堆積在消息泵。 – Servy

0

謝謝你的所有答案。所提供的描述現在對我更有意義。

也是以前的辯論:消息框確實阻塞了線程。它陷入了10%,然後崩潰了我的電腦(VM盒)。

現在我唯一的問題是,e.results正在返回一個項目數組。但它是對象。

我很難找回數據。

public void StartBackgroundWorker() 
{ 

    BackgroundWorker NewWorker = new BackgroundWorker(); 
    NewWorker.DoWork += new DoWorkEventHandler(NewWorker_DoWork); 
    NewWorker.ProgressChanged += new ProgressChangedEventHandler(NewWorker_ProgressChanged); 
    NewWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(NewWorker_RunWorkerCompleted); 
    NewWorker.WorkerReportsProgress = true; 

    NewWorker.RunWorkerAsync(); 
} 

void NewWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    List<string> ReturnResults = new List<string>(); 
    BackgroundWorker worker = sender as BackgroundWorker; 

    ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select StatusCode from Win32_PingStatus where address = 'Metabox-PC'"); 
    ManagementObjectCollection objCollection = searcher.Get(); 
    foreach (ManagementObject Results in objCollection) 
    { 
     ReturnResults.Add(Results["StatusCode"].ToString()); 
    } 
    e.Result = ReturnResults; 

    // Perform a time-consuming operation and report progress. 
    System.Threading.Thread.Sleep(1); 
} 

private void NewWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    txtPingable.text = e.Result; 
}