2017-04-17 125 views
1

請幫我理解出了什麼問題。我有一個進度條方法來開始在任務中運行進度欄。 Base類是保存來自另一個類的更新值的靜態類。下面是我的代碼:Dispatcher內部拋出異常'System.OutOfMemoryException'

private void startProgressBarBA() 
    { 
     int tempBA = 0; 
     proBing.Maximum = Int32.Parse(cboGeoThreshold.Text); 

     CancellationTokenSource bingBarToken = new CancellationTokenSource(); 
     Task bingTask = Task.Factory.StartNew(() => 
     { 
      while (!bingBarToken.Token.IsCancellationRequested) 
      { 
       if (tempBA != Base.proBaValue)//Reduce the number of same value assigned. 
       { 
        try 
        { 
         Dispatcher.BeginInvoke(new Action(() => 
         { 
          if (proBing.Value == proBing.Maximum) 
          { 
           proBing.Value = 0; 
           Base.proBaValue = 0; 
          } 
          proBing.Value = Base.proBaValue; 
          tempBA = Base.proBaValue; 
          baRecord.Content = proBing.Value + "/" + proBing.Maximum; 
         } 
         )); 
        } 
        catch(OutOfMemoryException e) 
        { 
         throw e; 
        } 
       } 
       if (Base.checkTaskBA == false) 
       { 
        bingBarToken.Cancel(); 
       } 
      } 
     },bingBarToken.Token, TaskCreationOptions.LongRunning,TaskScheduler.Default); 
    } 

異常會在一定時間後發生,而

Dispatcher.BeginInvoke 

已經凸顯。以下是例外信息:

System.OutOfMemoryException was unhandled by user code 
    HResult=-2147024882 
    Message=Exception of type 'System.OutOfMemoryException' was thrown. 
    Source=View 
    StackTrace: 
    at View.MainWindow.<>c__DisplayClass21_0.<startProgressBarBA>b__0() in C:\Wade\GeocodingApp\Geocoder_v21_Rev_pcode\View\MainWindow.xaml.cs:line 331 
    at System.Threading.Tasks.Task.InnerInvoke() 
    at System.Threading.Tasks.Task.Execute() 
    InnerException: 

如何解決此問題?是否因爲

new Action() 

會導致OutOfMemoryException?感謝大家的幫助。

+1

這裏只是一個猜測,但它看起來像你在任務中的「while」循環沒有延遲。這意味着你正在很快循環該循環,並且正在分派器隊列上創建大量異步「調用」消息 - 毫無疑問,這會耗盡所有內存......它們處理速度不夠快正在建設中(即必須有100萬個/可能是數百萬個創建的「行動」對象)。可能的解決方案....在你的while循環中加入某種「等待」,例如一個Thread.Sleep(100) - 你不需要經常發送它們來指示進度。 –

回答

2

這裏只是一個猜測,但它看起來像你在任務中的「while」循環沒有延遲。

這意味着你正在通過該循環非常快速地循環,並在Dispatcher隊列上創建大量異步「調用」消息 - 毫無疑問,這消耗了所有內存......它們不是處理速度足夠快,所以正在建立(即必須有100萬個/可能是數百萬個「行動」對象創建)。

可能的解決方案....在while循環中加入某種「等待」,例如,一個Thread.Sleep(100) - 你不需要經常發送它們來指示進度。

private void startProgressBarBA() 
{ 
    int tempBA = 0; 
    proBing.Maximum = Int32.Parse(cboGeoThreshold.Text); 

    CancellationTokenSource bingBarToken = new CancellationTokenSource(); 
    Task bingTask = Task.Factory.StartNew(() => 
    { 
     while (!bingBarToken.Token.IsCancellationRequested) 
     { 
      if (tempBA != Base.proBaValue)//Reduce the number of same value assigned. 
      { 
       try 
       { 
        Dispatcher.BeginInvoke(new Action(() => 
        { 
         if (proBing.Value == proBing.Maximum) 
         { 
          proBing.Value = 0; 
          Base.proBaValue = 0; 
         } 
         proBing.Value = Base.proBaValue; 
         tempBA = Base.proBaValue; 
         baRecord.Content = proBing.Value + "/" + proBing.Maximum; 
        } 
        )); 
       } 
       catch(OutOfMemoryException e) 
       { 
        throw e; 
       } 
      } 
      if (Base.checkTaskBA == false) 
      { 
       bingBarToken.Cancel(); 
      } 

      Thread.Sleep(100); 
     } 
    },bingBarToken.Token, TaskCreationOptions.LongRunning,TaskScheduler.Default); 
} 
+0

是的。通過添加Thread.Sleep,問題已解決。非常感謝!! –