UI在大量计算时冻结

本文关键字:冻结 计算 UI | 更新日期: 2023-09-27 18:16:41

我正在将大文件加载到内存中,但是在此计算时,我的应用程序冻结了。

你知道我的代码有什么问题吗?

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

UI在大量计算时冻结

我将把您的示例转换为如下内容:

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

我不确定这是否是您的问题的原因,但是您正在为后台工作器回调中设置args.Handled,因此它将在drop事件处理程序返回后被调用。它不会有预期的效果,因为它设置得太晚了,它可能会在事件处理中搞砸一些东西。