打破背景工作者的foreach

时间:2017-04-30 14:51:22

标签: c# foreach

我正在使用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();
    }
}

我该如何解决?

0 个答案:

没有答案