我有一個現有的系統與幾個長時間運行的操作。我希望找到一種簡單的方法來將這些操作包含在任務中,併爲用戶提供忙碌狀態通知。如何從獨立的任務更新我的winforms用戶界面?
這是使用.net 3.5,我正在使用TPL後端口。不幸的是異步/等待不能在這裏使用。
我試圖在下面顯示的一個簡單的測試表單中想出解決方案,並遇到了一些問題,包裹着我的頭。
下面的方法只顯示前2-3個任務,之後UI纔會更新,直到全部完成。爲什麼是這樣?
private void RunTaskUpdateBefore (string msg)
{
UpdateUI (msg);
Task task = Task.Factory.StartNew (() =>
{
// simulate some work being done
Thread.Sleep (1000);
});
task.Wait();
}
我希望這種方法將工作,但直到所有的任務都完成
private void ChildTaskExternalWait (string msg)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task task = Task.Factory.StartNew (() =>
{
Task.Factory.StartNew (() =>
{
UpdateUI (msg);
}, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
// simulate some work being done
Thread.Sleep (1000);
});
task.Wait(); // I assume this is the problem
}
下面的方法效果很好,但我不知道我是否可以在使用時不更新UI我的項目。這是一個相當大的複雜系統,操作發生在許多不同的類別中,並由我們無法修改的遺留系統控制。我假設我必須嘗試創建某種全局任務隊列來執行此操作?
private Task RunTaskInternalWaitOnPrevious (string msg, Task t1 = null)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task task = Task.Factory.StartNew (() =>
{
if (t1 != null)
{
t1.Wait();
}
Task.Factory.StartNew (() =>
{
UpdateUI (msg);
}, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
// simulate some work being done
Thread.Sleep (2000);
});
return task;
}
我測試的形式實現:
private void button1_Click (object sender, EventArgs e)
{
// Only displays the first 2-3 tasks. After that UI doesn't get updated until all are complete
RunTaskUpdateBefore ("Task 1");
RunTaskUpdateBefore ("Task 2");
RunTaskUpdateBefore ("Task 3");
RunTaskUpdateBefore ("Task 4");
RunTaskUpdateBefore ("Task 5");
RunTaskUpdateBefore ("Task 6");
RunTaskUpdateBefore ("Task 7");
// this works with any number of tasks
// Unfortunately I'm not sure if I can use it in my application (see above notes)
//var t1 = RunTaskInternalWaitOnPrevious ("Task 1");
//var t2 = RunTaskInternalWaitOnPrevious ("Task 2", t1);
// and so on
}
private void UpdateUI (string msg)
{
this.textBox1.Text += msg;
this.textBox1.Text += System.Environment.NewLine;
}
更新/澄清
*我的任務不能並行運行。
*我想通知用戶,每一步都在完成工作。
*任務運行時,沒有其他UI輸入可能發生。
這些任務沒有集中到一個特定的代碼段,並且發生在所有地方。我不知道如何描述我的情況,對不起。
我認爲在這一點上,我需要從一個簡短的例子開始。 – kbeal2k