ICommand异常,线程无法访问对象

时间:2015-11-12 09:45:02

标签: c# wpf multithreading visual-studio visual-studio-2010

我使用此类在网络启用和禁用按钮时 我在Gpfgateway上升了一个事件来通知网络 连接,按钮将被禁用,当我启动应用程序时 断开连接或连接网络后请求工作 例外。 Gpfgateway中的事件处理程序是Thread。

例外:

  

windowsBase.dll中的System.InvalidoperationException   附加信息:调用线程无法访问此,因为a   不同的线程拥有它。

参考这行代码:

 CanExecuteChanged(this, new EventArgs())

代码:

public class NewAnalysisCommand : ICommand
{
    private AnalysisViewModel analysisViewModel = null;
    private Measurement measurement;


    public NewAnalysisCommand(AnalysisViewModel viewAnalysis)
    {
        analysisViewModel = viewAnalysis;
        GpfGateway.GetInstance().SystemStatus += updateCanExecuteChanged;
    }

    /// <summary>Notifies command to update CanExecute property.</summary>
    private void updateCanExecuteChanged(object sender, EventArgs e)
    {
        CanExecuteChanged(this, new EventArgs());
    }
    bool ICommand.CanExecute(object parameter)
    {
        return GpfGateway.GetInstance().IsConnected;
    }

    public event EventHandler CanExecuteChanged;
    void ICommand.Execute(object parameter)
    { 
        NewAnalysisViewModel newAnalysisViewModel = new NewAnalysisViewModel();
        newAnalysisViewModel.NavigationResolver = analysisViewModel.NavigationResolver;

        // set CurrentPosition to -1 so that none is selected.
        analysisViewModel.Measurements.MoveCurrentToPosition(-1);
        analysisViewModel.Measurements.Refresh();
        if(((List<MeasurementViewModel>)(analysisViewModel.Measurements.SourceCollection)).Count == 0)
        {
            CanExecuteChanged(this, new EventArgs());
        }
        analysisViewModel.NavigationResolver.GoToAnalysisSettings(newAnalysisViewModel);

    }

    /// <summary>Notifies command to update CanExecute property.</summary>
    private void updateCanExecuteChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        CanExecuteChanged(this, new EventArgs());
    }
}

任何建议如何从该线程中使用该对象非常有用。

1 个答案:

答案 0 :(得分:0)

崩溃的原因很可能是因为GUI线程上没有发生网络事件 对CanExecuteChanged的调用用于修改作为GUI对象的按钮 但GUI对象只能在GUI线程上修改。

快速修复:

public class NewAnalysisCommand : ICommand
{
   // ...
   private Dispatcher dispatcher;
   public NewAnalysisCommand()
   {
      // The command captures the dispatcher of the GUI Thread
      dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
   }
   private void updateCanExecuteChanged(object sender, NotifyCollectionChangedEventArgs e)
   {
      // With a little help of the disptacher, let's go back to the gui thread.
      dispatcher.Invoke( () => { 
             CanExecuteChanged(this, new EventArgs()); } 
      );
   }
}

此致