2014-07-07 31 views
0

我有一個Silverlight網站正在調用WCF服務,以便它可以做一些服務器端加載。 WCF調用是異步的,因爲它的Silverlight就緒,所以在完成時,我正在讀取CompletedEventArgs中的數據以加載該類。但是,我不確定範圍如何工作。新任務的範圍與data相同嗎?它似乎沒有設置爲true。我知道該服務正在工作,因爲異步調用正在發生,但是我無法調試完成事件觸發,因爲我無法將調試器附加到「ASP.net-hosted-Silverlight」(有沒有辦法獲得圍繞這個?我很想能夠在其.aspx託管的情況下調試Silverlight ...)。我想出了這個this link.我目前正在測試我的項目,但我仍然好奇這個範圍的工作原理。範圍界定如何爲Task.Factory.Startnew工作?

感謝您的幫助!

編輯:我意識到這可能是結構此功能的可怕的方式,我彌補其他建議:)

// Objects constructor calls async WCF task, upon completion of which (grammar?) 
// sets IsComplete to true 
Foo data = new Foo(param); 

Task waitForComplete = Task.Factory.StartNew(() => 
    { 
     while (!data.IsComplete) 
     { 
      // Wait 1 second, then poll again 
      System.Threading.Thread.Sleep(1000 * 1); 
     } 
    }); 

Task.WaitAll(new Task[] { waitForComplete }); 

// Now that the task has completed, we can access its data 
bar.AddRange(data.GetFoo()); 
+1

你可以只調用'Wait'的任務,或者只是對旋最初的線程。它不清楚在這裏使用「Task」爲你做什麼。 –

+0

-.-你說得很好。它對我來說絕對沒有任何影響:)這是週一的其中一個......我將只有'while'循環 – Adam

+0

@ADam但我認爲問題在於你阻止了主線程,這可能會阻止完成並設置IsComplete的Foo任務... –

回答

1

一般情況下,你被呼叫阻塞主線程到Task.WaitAllFoo類很可能試圖將回調發布到該線程上,這永遠不會成功。這可以解釋爲什麼你永遠不會「完成」任務。

在一般情況下,這是一個更好的辦法是避免輪詢如果可能的話(一個選項,例如,是揭露Task/Task<T>給調用者,所以你可以附加一個持續存在)。不過,如果你不能改變的Foo實施,你可以關掉這個處理設置數據的延續,而不是阻止:

// Don't block 
// Task.WaitAll(new Task[] { waitForComplete }); 

// Instead, schedule a continuation that runs when the task is done... 
waitForComplete.ContinueWith(t => 
{ 
    // Now that the task has completed, we can access its data 
    bar.AddRange(data.GetFoo()); 
}, TaskScheduler.FromCurrentSynchronizationContext()); 
+0

這是一個很好的建議。雖然我在上面的示例中阻止了一個單獨的線程,但我肯定應該在默認情況下執行此操作。因此,即使我們從範圍返回,任務完成後對象將可用於「ContinueWith」表達式嗎? – Adam

+1

@Adam是的 - 你總是可以關閉lambda中的其他變量。範圍不是你原來的問題... –

+0

通過「張貼回調」你的意思是異步任務完成?因爲我知道這不是問題 - 我有一個前面的異步調用,其中的*完成的回調*被調用,因爲它會觸發第二個異步調用(我知道它正在觸發)。 – Adam