我正在使用Entity Framework迭代BackgroundWorker中的表
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
using (var db = new LibraryLogModel())
{
int count = 0;
var table = db.FrontOfficeAction.AsNoTracking()
.OrderBy(s => s.FrontOfficeSessionId)
.ThenBy(d => d.ActionDateTime);
foreach (var row in table)
{
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
count++;
_actionAnalyzer.AnalyzeAction(row);
if (count % 1000 == 0)
{
worker.ReportProgress(count);
}
}
}
}
排序只需30秒,然后foreach正常工作。 ReportProgress()更新进度条和标签。当分析结束时,引发了RunWorkerCompleted事件,一切都很好,没有异常。但是,如果我在分析过程中单击取消按钮并调用CancelAsync(),则会发生一些奇怪的魔法。
worker.CancellationPending为true,但未引发RunWorkerCompleted事件,并且在超时后出现SqlErrorCollection异常。
System.Data.SqlClient.SqlException was unhandled by user code
Class=11
ErrorCode=-2146232060
HResult=-2146232060
LineNumber=0
Message=Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding
Number=-2
Procedure=""
Server=.\SQLEXPRESS
Source=.Net SqlClient Data Provider
State=0
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryCloseInternal(Boolean closeReader)
at System.Data.SqlClient.SqlDataReader.Close()
at System.Data.Common.DbDataReader.Dispose(Boolean disposing)
at System.Data.Common.DbDataReader.Dispose()
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.Finally()
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.Dispose()
at System.Data.Entity.Internal.LazyEnumerator`1.Dispose()
at ECatalogRecommendations.Form1.bw_DoWork(Object sender, DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
InnerException:
ErrorCode=-2147467259
HResult=-2147467259
Message=Timeout expired
NativeErrorCode=258
InnerException:
如果将其包装在try-catch中,则会引发RunWorkerCompleted,但仅在相同的超时之后。
我尝试使用break而不是return,但它根本没有打破foreach循环,我得到了相同的异常。
我将后台工作者作为
运行private void btnStart_Click(object sender, EventArgs e)
{
if (!_worker.IsBusy)
{
int size;
using (var db = new LibraryLogModel())
{
size = db.FrontOfficeAction.Count();
}
progressBar.Minimum = 0;
progressBar.Maximum = size;
_worker.RunWorkerAsync();
}
}
我该如何解决?