如果用戶執行操作(例如刪除項目),則會立即從UI中刪除它們,然後使用TPL將它們從後臺線程的數據庫中刪除。問題是,如果用戶在後臺線程結束之前退出應用程序,則該項目永遠不會被刪除。如何等待我的異步操作在應用程序退出時完成?
在關閉應用程序之前是否有等待異步操作完成的標準方式?
我的異步調用是這樣的:
if (MyObjectList.Contains(obj)) MyObjectList.Remove(obj);
Task.Factory.StartNew(() => DAL<MyEntities>.DeleteObject(obj));
更新
下面是最終代碼我去了。我很高興看到它能夠正常工作,但讓我知道我是否可以改進它。我還有很多東西需要學習:)
public partial class App : Application
{
private List<Task> _backgroundTasks = new List<Task>();
public App()
{
EventSystem.Subscribe<TaskStartedMessage>((e) =>
{
_backgroundTasks.Add(e.Task);
});
EventSystem.Subscribe<TaskEndedMessage>((e) =>
{
if (_backgroundTasks.Contains(e.Task))
_backgroundTasks.Remove(e.Task);
});
}
protected override void OnExit(ExitEventArgs e)
{
Task.WaitAll(_backgroundTasks.Where(p => !p.IsCompleted).ToArray(), 30000);
base.OnExit(e);
}
}
和啓動重要的背景任務時,我使用這個語法:
var task = Task.Factory.StartNew(() => DAL<MyEntities>.DeleteObject(obj));
EventSystem.Publish<TaskStartedMessage>(new TaskStartedMessage(task));
await task;
EventSystem.Publish<TaskEndedMessage>(new TaskEndedMessage(task));
我使用AsyncCTP爲await
/async
和微軟Prism的EventAggregator
爲事件系統。
最終代碼看起來不錯,但是我刪除了foreach並將其替換爲:Task.WaitAll(_backgroundTasks.ToArray());我想不出你的實現可能會造成什麼麻煩,但我猜測如果他們實現了這個靜態方法,他們有一個問題。 –
@Baboon謝謝,我不知道有一個'Task.WaitAll()'方法,我可以在任務列表上使用 – Rachel