我有一個Backgroundworker,它從數據庫中收集大量數據。我想在線程上設置一個超時限制,這樣如果它在設定的時間量之後沒有返回結果,進程將被取消。Timer Elapsed Event不執行所有操作
我在啓動BackgroundWorker的同時在主線程上啓動一個定時器。
如果我故意讓BGW進入睡眠狀態,計時器將過去並調用.Elapsed事件。然後取消後臺工作,但它沒有成功完成我想要它完成的其他操作,它們更新GUI上的狀態欄並拋出MessageBox。我不明白爲什麼不能,任何人都可以幫忙?
超時和睡眠被故意設置爲測試。
/// <summary>
/// loads Assets by group ID
/// Populates Grid on asset listing page
/// </summary>
/// <param name="groupId"></param>
/// <param name="user"></param>
internal void PopulateGridAssetsByGroup(int groupId, User user)
{
//update statusbar
AfMainWindow.MainWindow.UpdateStatusBar("Loading Assets...");
//setup BG worker
populateGridAssetsWorker = new BackgroundWorker {WorkerSupportsCancellation = true, WorkerReportsProgress = false};
populateGridAssetsWorker.DoWork += populateGridAssetsWorker_DoWork;
populateGridAssetsWorker.RunWorkerCompleted += populateGridAssetsWorker_RunWorkerCompleted;
//setup timer which will cancel the background worker if it runs too long
cancelTimer = new Timer {Interval = 2000, Enabled = true, AutoReset = false};
cancelTimer.Elapsed += cancelTimer_Elapsed;
cancelTimer.Start();
populateGridAssetsWorker.RunWorkerAsync(groupId); //start bg worker
}
void cancelTimer_Elapsed(object sender, ElapsedEventArgs e)
{
populateGridAssetsWorker.CancelAsync();
cancelTimer.Stop();
AfMainWindow.MainWindow.UpdateStatusBar("Could not load assets, timeout error");
MessageBox.Show("Operation Timed Out\n\nThe Server did not respond quick enough, please try again",
"Timeout", MessageBoxButton.OK, MessageBoxImage.Exclamation, MessageBoxResult.OK);
AfMainWindow.MainWindow.Busy.IsBusy = false;
}
/// <summary>
/// when bg worker complete, update the AssetGrid on Asset Listing Page with results
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void populateGridAssetsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
cancelTimer.Stop();
//my thread complete processing
}
/// <summary>
/// Perform the DB query and collect results for asset listing
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void populateGridAssetsWorker_DoWork(object sender, DoWorkEventArgs e)
{
var assetListByGroup = new List<AssetLinked>();
Thread.Sleep(5000);
if (populateGridAssetsWorker.CancellationPending)
{
return;
}
try
{
//My SQL actions
if (populateGridAssetsWorker.CancellationPending)
{
return;
}
}
catch (Exception ex)
{
Globals.AFWideSettings.GeneralErrorMessage(ex.Message);
}
}
和反對票是爲了什麼? – Damo
+1來取消downvote。對我來說似乎是一個合理的問題。 – PeteH
這似乎是一個斷點的主要候選人,大概你已經做到了這一點?那麼你是說你點擊了MessageBox.Show ....但是沒有收到消息框? – PeteH