Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与backgroundworker的进度对话框的ShowDialog上出现wpf异常_C#_Wpf_Backgroundworker - Fatal编程技术网

C# 与backgroundworker的进度对话框的ShowDialog上出现wpf异常

C# 与backgroundworker的进度对话框的ShowDialog上出现wpf异常,c#,wpf,backgroundworker,C#,Wpf,Backgroundworker,我按照我在网上看到的一个例子创建了一个进度对话框(下面的代码),在主线程中,我调用 ProgressDialog pd = new ProgressDialog("Loading File: ", VCDFileName); pd.Owner = Application.Current.MainWindow; pd.WindowStartupLocation = WindowStartupLocation.CenterOwner; ModuleHierarchyVM.TopLev

我按照我在网上看到的一个例子创建了一个进度对话框(下面的代码),在主线程中,我调用

  ProgressDialog pd = new ProgressDialog("Loading File: ", VCDFileName);
  pd.Owner = Application.Current.MainWindow;
  pd.WindowStartupLocation = WindowStartupLocation.CenterOwner;
  ModuleHierarchyVM.TopLevelModules.Clear();


  VCDData TempVCDOutput = null;
  Action handler = delegate
  {
      VCDParser.ParseVCDFileForAllPorts(VCDFileName, this, pd.Worker, ModuleHierarchyVM.TopLevelModules, out TempVCDOutput);
  };

  pd.SetBGWorkerDelegate(handler);
  pd.ShowDialog();
我认为错误发生在传递给委托的函数中。我想我得到了两个例外(每个线程上可能有一个例外?),第一个说

目标异常未处理。调用的目标已引发异常

我认为这个异常是由UI线程引发的,因为有时在异常显示之前传递给委托的函数中会遇到断点,有时则不会

然后在按下f5键一段时间后,通过在后台执行的函数中的许多断点

我最终返回到UI线程和pd.ShowDialog()并得到以下异常:

未处理InvalidOperationException。只能在隐藏窗口上调用ShowDailog

如果异常发生在传递给委托的函数中,我放置了一堆try-catch块来尝试捕捉异常,但我没有捕捉到它。似乎没有

“进度”对话框中的代码

  public partial class ProgressDialog : Window
  {
    BackgroundWorker _worker;
    public BackgroundWorker Worker
    {
      get { return _worker; }
    }


    public string MainText
    {
      get { return MainTextLabel.Text; }
      set { MainTextLabel.Text = value; }
    }

    public string SubText
    {
      get { return SubTextLabel.Text; }
      set { SubTextLabel.Text = value; }
    }



    public bool IsCancellingEnabled
    {
      get { return CancelButton.IsVisible; }
      set { CancelButton.Visibility = value ? Visibility.Visible : Visibility.Collapsed; }
    }


    private bool _Cancelled = false;
    public bool Cancelled
    {
      get { return _Cancelled; }
    }

    private Exception error = null;
    public Exception Error
    {
      get { return error; }
    }


    private object result = null;
    public object Result
    {
      get { return result; }
    }


    /// <summary>
    /// Represents the method that will handle the DoWork event from the backgroundowkrker
    /// </summary>
    private Action workerCallback;

    private object BackgroundWorkerArgument;


    public ProgressDialog(string MainText, string SubText)
      : this()
    {
      this.MainText = MainText;
      this.SubText = SubText;
    }


    public ProgressDialog()
    {
      InitializeComponent();

      this.Loaded += new RoutedEventHandler(ProgressDialog_Loaded);

      _worker = new BackgroundWorker();
      _worker.WorkerReportsProgress = true;
      _worker.WorkerSupportsCancellation = true;


      _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
      _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
      _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
      Closing += new CancelEventHandler(ProgressDialog_Closing);
    }

    void ProgressDialog_Loaded(object sender, RoutedEventArgs e)
    {
      _worker.RunWorkerAsync(BackgroundWorkerArgument);
    }

    void ProgressDialog_Closing(object sender, CancelEventArgs e)
    {
      //if progress dialog is open
      if (DialogResult == null)
      {
        MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show("Are you sure you wish to cancel?",
           "Confirmation", System.Windows.MessageBoxButton.YesNo);
        if (messageBoxResult == MessageBoxResult.Yes)
        {
          if (_worker.IsBusy)
          {
            //notifies the async thread that a cancellation has been requested.
            _worker.CancelAsync();
          }
          DialogResult = false;
        }
        else
        {

          e.Cancel = true;
        }
      }
      else
      {

        if (_worker.IsBusy)
        {
          //notifies the async thread that a cancellation has been requested.
          _worker.CancelAsync();
        }
      }

    }




    void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      if (!Dispatcher.CheckAccess())
      {
        //run on UI thread
        RunWorkerCompletedEventHandler handler = _worker_RunWorkerCompleted;
        Dispatcher.Invoke(handler, null, DispatcherPriority.SystemIdle, new object[] { sender, e });
        return;
      }
      else
      {
        if (e.Error != null)
        {
          error = e.Error;
        }
        else if (!e.Cancelled)
        {
          //assign result if there was neither exception nor cancel
          result = e.Result;
        }
        ProgressBar.Value = ProgressBar.Maximum;
        CancelButton.IsEnabled = false;


        //set the dialog result, which closes the dialog
        if (DialogResult == null)
        {
          if (error == null && !e.Cancelled)
          {
            DialogResult = true;
          }
          else
          {
            DialogResult = false;
          }
        }
      }

    }

    void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
      if (!Dispatcher.CheckAccess())
      {
        //run on UI thread
        ProgressChangedEventHandler handler = _worker_ProgressChanged;
        Dispatcher.Invoke(handler, null, DispatcherPriority.SystemIdle, new object[] { sender, e });
        return;
      }
      else
      {
        if (e.ProgressPercentage != int.MinValue)
        {
          ProgressBar.Value = e.ProgressPercentage;
        }

      }

    }

    void _worker_DoWork(object sender, DoWorkEventArgs e)
    {
      try
      {
        if ((_worker.CancellationPending == true))
        {
          //cancel the do work event
          e.Cancel = true;
        }
        else
        {
          // Perform a time consuming operation and report progress.
          workerCallback();
        }

      }
      catch (Exception)
      {
        //disable cancelling and rethrow the exception
        Dispatcher.BeginInvoke(DispatcherPriority.Normal,
          new Action(delegate { CancelButton.SetValue(Button.IsEnabledProperty, false); }), null);
        throw;
      }
    }




    public void SetBGWorkerDelegate(Action workHandler)
    {
      SetBGWorkerDelegate(null, workHandler);
    }
    public void SetBGWorkerDelegate(object argument, Action workHandler)
    {
      //store reference to callback handler and launch worker thread
      workerCallback = workHandler;
      BackgroundWorkerArgument = argument;



    }


    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
      MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show("Are you sure you wish to cancel?", 
        "Confirmation", System.Windows.MessageBoxButton.YesNo);
      if (messageBoxResult == MessageBoxResult.Yes)
      {
        if (_worker.IsBusy)
        {
          //notifies the async thread that a cancellation has been requested.
          _worker.CancelAsync();
        }
        DialogResult = false;        
      }


    }
  }
}
公共部分类进度对话框:窗口
{
背景工人;
公共背景工作者
{
获取{return\u worker;}
}
公共字符串主文本
{
获取{return MainTextLabel.Text;}
设置{MainTextLabel.Text=value;}
}
公共字符串潜文本
{
获取{return subtextlab.Text;}
设置{subtextlab.Text=value;}
}
公共场所被清除
{
获取{return CancelButton.IsVisible;}
设置{CancelButton.Visibility=value?Visibility.Visibility:Visibility.Collapsed;}
}
private bool_Cancelled=假;
公共图书馆取消
{
获取{return\u Cancelled;}
}
私有异常错误=null;
公共异常错误
{
获取{返回错误;}
}
私有对象结果=null;
公共对象结果
{
获取{返回结果;}
}
/// 
///表示将从backgroundowkrker处理DoWork事件的方法
/// 
私人行动回扣;
私有对象背景;
公共进程对话框(字符串主文本、字符串子文本)
:此()
{
this.MainText=MainText;
this.SubText=潜文本;
}
公共对话()
{
初始化组件();
this.Loaded+=新的RoutedEventHandler(ProgressDialog\u Loaded);
_worker=新的BackgroundWorker();
_worker.WorkerReportsProgress=true;
_worker.worker支持扫描单元=true;
_worker.DoWork+=新的doworkereventhandler(\u worker\u DoWork);
_worker.ProgressChanged+=新的ProgressChangedEventHandler(\u-worker\u-ProgressChanged);
_worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(\u-worker\u-RunWorkerCompleted);
关闭+=新的CancelEventHandler(ProgressDialog\u关闭);
}
已加载void ProgressDialog_(对象发送器,路由目标)
{
_worker.RunWorkerAsync(backgroundworkeragument);
}
void ProgressDialog\u关闭(对象发送方,取消事件参数)
{
//如果“进度”对话框处于打开状态
如果(DialogResult==null)
{
MessageBoxResult MessageBoxResult=System.Windows.MessageBox.Show(“您确定要取消吗?”,
“确认”,System.Windows.MessageBoxButton.YesNo);
if(messageBoxResult==messageBoxResult.Yes)
{
如果(\u worker.IsBusy)
{
//通知异步线程已请求取消。
_worker.CancelAsync();
}
DialogResult=false;
}
其他的
{
e、 取消=真;
}
}
其他的
{
如果(\u worker.IsBusy)
{
//通知异步线程已请求取消。
_worker.CancelAsync();
}
}
}
void\u worker\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge)
{
如果(!Dispatcher.CheckAccess())
{
//在UI线程上运行
RunWorkerCompletedEventHandler处理程序=\u worker\u RunWorkerCompleted;
Invoke(handler,null,DispatcherPriority.SystemIdle,新对象[]{sender,e});
返回;
}
其他的
{
如果(例如错误!=null)
{
误差=e.误差;
}
否则,如果(!e.取消)
{
//如果既没有异常也没有取消,则分配结果
结果=e.结果;
}
ProgressBar.Value=ProgressBar.Maximum;
CancelButton.IsEnabled=false;
//设置对话框结果,关闭对话框
如果(DialogResult==null)
{
如果(错误==null&&!e.已取消)
{
DialogResult=true;
}
其他的
{
DialogResult=false;
}
}
}
}
void\u worker\u ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
如果(!Dispatcher.CheckAccess())
{
//在UI线程上运行
ProgressChangedEventHandler处理程序=\u worker\u ProgressChanged;
Invoke(handler,null,DispatcherPriority.SystemIdle,新对象[]{sender,e});
返回;
}
其他的
{
如果(例如,ProgressPercentage!=int.MinValue)
{
ProgressBar.Value=e.ProgressPercentage;
}
}
}
void\u worker\u DoWork(对象发送方,DoWorkEventArgs e)
{
尝试
{
if(_worker.CancellationPending==true))
{
//取消do work事件
e、 取消=真;
}
其他的
{
//执行耗时的操作并报告进度。
workerCallback();
}
}
捕获(例外)
{
//禁用取消并重新显示异常
Dispatcher.BeginInvoke(Dispat