4

I am loading huge files to the memory but on this calculation my application is freezes .

Any idea what is the issue with my code ?

public void Drop(DragEventArgs args)
{
  BackgroundWorker worker = new BackgroundWorker();
  string fileName = IsSingleTextFile(args);
  if (fileName == null) return;
  worker.DoWork += (o, ea) =>
  {
    try
    {
      StreamReader fileToLoad = new StreamReader(fileName);
      string filecontent = fileToLoad.ReadToEnd();
      fileToLoad.Close();
      // providing the information to the UI thread

      Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
        new Action(() => SfmLogFile = filecontent));
    }
    catch (Exception)
    {
      throw;
    }
  };

  worker.RunWorkerCompleted += (o, ea) =>
  {
    args.Handled = true;
    IsBusy = false;
  };

  // Mark the event as handled, so TextBox's native Drop handler is not called.

  IsBusy = true;
  worker.RunWorkerAsync();

}
Udo Held
  • 12,314
  • 11
  • 67
  • 93
Night Walker
  • 20,638
  • 52
  • 151
  • 228
  • What is "// providing the information to the UI thread" consist of? – Tigran Dec 04 '11 at 09:26
  • What is SfmLogFile? Why do you set args.Handled in RunWorkerCompleted instead of the body of Drop eventhandler? – Eugene Cheverda Dec 04 '11 at 09:46
  • @Tigran ,SfmLogFile = filecontent I am just updating the string that my UI is data binded to. – Night Walker Dec 04 '11 at 09:46
  • 2
    So considering that file is huge, and you load ALL content inside that string, and after that all content you push on UI, IMHO, that could be a problem actually. Cause UI update, even if called form other thread will use main UI thread to update itself. So if the strings is really long it will take a time. – Tigran Dec 04 '11 at 09:54

2 Answers2

2

I'd transform your sample to something like this:

public void Drop(DragEventArgs args)
{
  string fileName = IsSingleTextFile(args);
  if (fileName == null) return;
  // It is better to create worker after check for file name.
  BackgroundWorker worker = new BackgroundWorker();
  worker.DoWork += (o, ea) =>
  {
    try
    {
      string filecontent = ReadAllText(fileName);    
      ea.Result = fileContent;
    }
    catch (Exception)
    {
      throw;
    }
  };

  worker.RunWorkerCompleted += (o, ea) =>
  {
    var fileContent = ea.Result as string;
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
        new Action(() => SfmLogFile = filecontent));

    // if IsBusy propery is not on the UI thread, then you may leave it here
    // otherwise it should be set using the dispatcher too.
    IsBusy = false;
  };

  IsBusy = true;
  worker.RunWorkerAsync();
  // Mark the event as handled, so TextBox's native Drop handler is not called.    
  args.Handled = true;
}
Eugene Cheverda
  • 8,760
  • 2
  • 33
  • 18
1

I am not sure if it's the cause of your problem, but you are setting args.Handled in a callback for the background worker, so it will be called after the drop event handler has returned. It won't have the desired effect as it's set too late, and it might mess up something in the event handling.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005