Search code examples
c#wpfout-of-memorytaskdispatcher

Exception of type 'System.OutOfMemoryException' was thrown inside Dispatcher


Please help me to understand what went wrong. I have a progress bar method to start running the progress bar in a task. The Base class is the static class which holds the updated values from another class. Below is my code:

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);
    }

The exception will occurs after a certain time, and the

Dispatcher.BeginInvoke

has been highlighted. Here is the exception message:

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: 

How to solve this issue? Is it because the

new Action()

causes the OutOfMemoryException? Thanks for everyone's help.


Solution

  • Just a guess here, but it looks like you have no delay in that "while" loop in your task.

    That means you are cycling through that loop very quickly, and are creating a huge number of asynchronous "invoke" messages on the Dispatcher queue - no doubt this is eating up all the memory....they aren't being processed fast enough so are building up (i.e. must have 100s thousands/maybe millions of "Action" objects created).

    Possible solution....put some kind of "wait" in your while loop e.g. a Thread.Sleep(100) - you don't need to send them out that often to indicate the progress.

    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);
    }