2011-12-29 99 views
3

我對WPF很新穎。剛開始學習線程。線程的正確方法

這是我的場景: 我用一個名爲START的按鈕創建了一個程序。當單擊開始按鈕時,它開始在不同的線程中執行一些複雜的任務。在開始複雜任務之前,它還在另一個STA線程(技術上我不知道我在說什麼)創建了中的UI元素。

這裏是一個示例代碼:

// button click event 
private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    System.Threading.Thread myThread = new System.Threading.Thread(
     () => buttonUpdate("Hello ")); 
    myThread.Start(); 
} 

private void buttonUpdate(string text) 
{ 
    System.Threading.Thread myThread = new System.Threading.Thread(createUI); 
    myThread.SetApartmentState(System.Threading.ApartmentState.STA); 

    // set the current thread to background so that it's existant will totally 
    // depend upon existance of main thread. 
    myThread.IsBackground = true; 
    myThread.Start(); 

    // Please don't read this loop it's just for my entertainment! 
    for (int i = 0; i < 1000; i++) 
    { 
     System.Threading.Thread.Sleep(100); 
     button1.updateControl(new Action(
      () => button1.Content = text + i.ToString())); 
     if (i == 100) 
      break; 
    } 

    // close main window after the value of "i" reaches 100; 
    this.updateControl(new Action(()=>this.Close())); 
} 

// method to create UI in STA thread. This thread will be set to run 
// as background thread. 


private void createUI() 
{ 
    // Create Grids and other UI component here 
} 

上面的代碼成功地做什麼,我想做的事情。但你認爲這是正確的方式嗎?到目前爲止,我在這裏沒有任何問題。

編輯:哎呀,我忘了提這個類:

public static class ControlException 
{ 
    public static void updateControl(this Control control, Action code) 
    { 
     if (!control.Dispatcher.CheckAccess()) 
      control.Dispatcher.BeginInvoke(code); 
     else 
      code.Invoke(); 
    } 
} 
+0

如果你真正理解你在說什麼,可能會有所幫助。當你瞭解STA線程的含義時,做一些研究回來。 – 2011-12-29 18:40:41

回答

2

如果您使用的是.NET 4.0,你可能要考慮使用從Task parallel libraryTask類。自從你說你是線程新手之後,請閱讀它。使用起來更加靈活。

而且我認爲這個鏈接可能對你很有幫助:

http://www.albahari.com/threading/

+0

我無法使用任務使用UI元素。請參閱:http://stackoverflow.com/questions/8665158/a-very-basic-explanation-for-threading-in-wpf – user995387 2011-12-29 18:02:25

+1

@ user995387 - 您可以使用TaskScheduler.FromCurrentSynchronizationContext方法獲取當前同步的TaskScheduler上下文。看看這篇文章:http://stackoverflow.com/questions/5971686/how-to-create-a-task-tpl-running-a-sta-thread – TheBoyan 2011-12-29 18:04:51

+0

謝謝你,這是一個很大的幫助。我會嘗試這種方式。 – user995387 2011-12-29 18:08:43

2

似乎沒有什麼理由使用2個線程。您可以在主線程上執行createUI()。當它變成填充這些控件的時候,這將變得很複雜。

+0

非常感謝您的建議。其實我真的忽視了這一點。 :P – user995387 2011-12-29 18:00:27

+0

順便說一下,如果我使用tat createUI()來創建flowdocument,那麼它會很好嗎?我想打印它也將在後臺工作 – user995387 2011-12-30 06:57:45

1

只有一個線程可以與UI進行交互。如果您要將控件添加到頁面或窗口,那麼您必須使用創建頁面或窗口的線程。典型的場景是使用線程在後臺創建昂貴的數據或對象,然後在回調(在主線程上運行)檢索結果並將適當的數據綁定到UI。看看使用BackgroundWorker,因爲它會爲您處理很多線程細節。 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx爲什麼你想在另一個上創建UI對象?

+1

將其添加到流程文檔並打印它.... – user995387 2011-12-30 06:40:57

相關問題