2016-09-07 48 views
3

我有一个类,它应该表现出一些信息给用户,当一些操作的状态改变时,这样的:创建异步线程内的物体引起STA例外

public static class AutoUpdater 
    { 
     public static async void AutoUpdateCheck() 
     { 
      UpdaterStatus.CurrentUpdateStatus = await UpdaterLogic.CheckForUpdateAsync(); 
     } 

     public static void OnStatusChanged() 
     { 
       switch (UpdaterStatus.CurrentStatus) 
       { 
        case UpdateStatus.UpdateFound: 
         { 
          Message ToAdd = new Message("some params"); //Exception here 
          MessagesManager.AddNewMessage(ToAdd); 
          break; 
         } 
        //some other cases 
       } 
     } 

当应用程序启动时,我同意AutoUpdater像这样的事件:

UpdaterStatus.EventStatusChanged += (sender, args) => { AutoUpdater.OnStatusChanged(); }; 

我得到的例外是:“调用线程必须为STA,因为许多UI组件都需要这个”。

但是,我不能自己创建STA线程,然后将新创建的消息添加到其父控件,因为这样我得到一个异常,并说“该对象属于另一个线程”。

有什么解决方法吗?

+3

不要创建一个后台线程的UI元素。为消息创建视图模型,并使用数据模板对其进行可视化处理,例如在ItemsControl中。 – Clemens

+0

控件只能从创建它们的线程访问。还应该在UI线程上创建和访问它们。如果你想从另一个线程更新它们,那么你应该使用分派器。请参阅用户'tym32167'提供的答案。 –

回答

4

您应该从UI线程创建UI控件。您可以尝试在这里

Application.Current.Dispatcher.Invoke(/* your action here*/() => {/* creating UI controls */}); 
+0

我想要做的事情是在WinForms项目中,同时也使用WPF控件(消息类)。没有'Application.Current'这样的事情,但是,我试图做的是:Dispatcher.CurrentDispatcher.Invoke(new Action(()=> MessagesManager.AddNewMessage(new Message(“some params”)))) ;'和异常仍然是一样的,我做错了什么? –

+0

你需要找到UI线程的分派器。当你尝试调用Dispatcher.CurrentDispatcher时,你会得到当前线程的Dispatcher,但当前线程不是UI,这就是为什么这不能解决你的问题。 – tym32167

+0

关于Application.Current,你可以试试这个http://stackoverflow.com/questions/35902815/why-does-application-current-null-in-a-winforms-application希望它有帮助。 – tym32167

0

更新使用调度你的函数如下

public void OnStatusChanged() 
    { 
     if (this.Dispatcher.CheckAccess()) 
     { 
      switch (UpdaterStatus.CurrentStatus) 
      { 
       case UpdateStatus.UpdateFound: 
        { 
         Message ToAdd = new Message("some params"); //Exception here 
         MessagesManager.AddNewMessage(ToAdd); 
         break; 
        } 
       //some other cases 
      } 
     } 
     else 
      this.Dispatcher.Invoke(new Action(OnStatusChanged)); 
    } 
+0

可悲的是,没有任何东西作为'this.Dispatcher' –

+0

好吧我忘了你已经使用了静态方法,所以这是不可用的静态方法内,而不是你可以使用任何形式或控制对象 –