我可能會對這一切都錯,但我卡住了。我有一個GUI應用程序,它生成一個單獨的線程,從服務器下載一堆數據。當這個下載線程完成後,我希望它向主線程發送一個信號,以便它知道它現在可以顯示下載的數據。異步信號主線程
我已經打過電話調用(從我的主要形式)來調用一個委託做的工作顯示,但這塊我的下載線程,直到其完成。我有點想做一個沒有EndInvoke的BeginInvoke,但我知道它不適合這樣做。
我可能會對這一切都錯,但我卡住了。我有一個GUI應用程序,它生成一個單獨的線程,從服務器下載一堆數據。當這個下載線程完成後,我希望它向主線程發送一個信號,以便它知道它現在可以顯示下載的數據。異步信號主線程
我已經打過電話調用(從我的主要形式)來調用一個委託做的工作顯示,但這塊我的下載線程,直到其完成。我有點想做一個沒有EndInvoke的BeginInvoke,但我知道它不適合這樣做。
有幾個選項。
我個人最喜歡的是使用TPL。在您的UI線程,你可以做一個TaskFactory
,像這樣:
// Given:
// TaskFactory uiFactory;
uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
然後,在你的後臺任務,你可以創建一個Task
更新您的UI:
var task = uiFactory.StartNew(() => UpdateUserInterface(data));
這將元帥UI線程正確,類似於調用BeginInvoke
。如果需要阻止,則可以撥打task.Wait()
(如果Update方法返回值,則爲task.Result
)。
謝謝。這正是我一直在尋找的東西。必須傳遞一個'Control'的實例,所以你可以'一直調用'對我來說似乎是錯誤的。 –
@FrankWeindel關於這一點的好處是它可以與任何UI框架一起工作,甚至可以與WCF的同步上下文一樣使用。在使用TPL時,您不會綁定到特定的UI框架(WPF,Silverlight,WinForms等),而且它也很好地轉換爲C#5的異步。 –
有幾種選擇:
「的TPL有其他調度,除了默認的,還允許您創建自定義調度一種是基於當前同步上下文TPL提供調度器,它可以被用來確保我的任務在UI線程上執行「。 (Source article):
var ui = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.ContinueWhenAll(tasks.ToArray(),
result =>
{
var time = watch.ElapsedMilliseconds;
label1.Content += time.ToString();
}, CancellationToken.None, TaskContinuationOptions.None, ui);
與下載方案的情況下,.ContinueWith()
延續將是適當的。
你可以張貼一些代碼? Control.Invoke(委託)應該工作得很好 –
BeginInvoke不需要EndInvoke。我始終在沒有EndInvoke的情況下使用BeginInvoke。 – Casperah
也檢查http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx – MBen