2010-09-21 145 views
9

嗨,通常我會用Background Worker來做這件事,但我想用C#Task來做,而不是更好地理解Task。運行多個C#任務異步

的事情是,我有以下特性

private int _number1; 
    public int Number1 
    { 
     get { return _number1; } 
     set { _number1 = value; OnPropertyChanged("Number1");} 
    } 

    private int _number2; 
    public int Number2 
    { 
     get { return _number2; } 
     set { _number2 = value; OnPropertyChanged("Number2");} 
    } 

請注意,我用的是INotifyPropertyChanged的一類。

Number1 = Task<int>.Factory.StartNew(() => GenerateResult()).Result; 
Number2 = Task<int>.Factory.StartNew(() => GenerateResult2()).Result; 

GenerateResult和GenerateResult2只是沉悶的方法,誰睡覺,然後返回一個數字。

如何讓這項工作異步?由於現在,當GenerateResult()完成時,首先調用GenerateResult2()。

我需要它能夠工作異步,因爲我不知道什麼時候每個任務要完成或即使完成。

回答

13

當您獲得Result屬性時,您正在等待任務完成。它將在後臺線程上執行,但是在開始下一個線程之前,您正在主線程中等待完成。

有關詳細信息,請參閱MSDN doc

你應該能夠剛剛從後臺線程分配你的屬性:

Task<int>.Factory.StartNew(() => Number1 = GenerateResult()); 

WPF數據綁定將take care of marshalling PropertyChanged事件到正確的調度線程。

+0

非常感謝Isak Savo工作完美,而且閱讀起來很簡單:-)更容易然後Backgroundworkers – gulbaek 2010-09-21 09:27:57

+0

任何任務都將在工作線程上始​​終執行,這並不是明確的。結果只是阻止調用它的線程,直到它準備好輸出數據或設置異常。 – 2011-02-05 11:29:55

+0

謝謝,我有一個調試線正在調用.Result,所以我可以做一個快速測試,並打破異步:O – John 2012-01-31 23:34:38

-4
Task<int>.Factory.StartNew(() => GenerateResult2()).ContinueWith(() => GenerateResult()); 
+5

除非我誤解了,這與OP代碼的語義完全相同 - 第二項任務在第一項任務完成之前未啓動。 – 2010-09-21 08:38:26

3

我檢查了這個:Task Parallelism (Task Parallel Library)它說,當使用System.Threading.Tasks.Task<TResult>任務運行異步,並可能以任何順序完成。 如果在計算完成之前訪問Result,則屬性將阻塞該線程,直到該值可用。

我認爲這意味着如果您在訪問.Result之前有一個值,就像您在示例代碼中所做的那樣,您將不得不等待它先完成。

這是有道理的,因爲Result屬性將不會填充,直到任務完成。

+2

沒有看到Isak Savo的答案已經指出訪問結果將等待任務完成。 – Nope 2010-09-21 08:46:13