【问题标题】:The application called an interface that was marshalled for a different thread - Windows Store App应用程序调用了为不同线程编组的接口 - Windows Store App
【发布时间】:2013-10-20 22:02:02
【问题描述】:

所以,首先我已经阅读了大量关于这个特定问题的线程,但我仍然不明白如何解决它。基本上,我正在尝试与 websocket 通信并将收到的消息存储在绑定到列表视图的可观察集合中。我知道我从套接字正确地得到了响应,但是当它尝试将它添加到可观察集合中时,它给了我以下错误:

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

我已经阅读了一些关于“调度”的信息以及其他一些信息,但我非常困惑!这是我的代码:

public ObservableCollection<string> messageList  { get; set; }
private void MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
    {
        string read = "";
        try
        {
            using (DataReader reader = args.GetDataReader())
            {
                reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                read = reader.ReadString(reader.UnconsumedBufferLength);
            }
        }
        catch (Exception ex) // For debugging
        {
            WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);
            // Add your specific error-handling code here.
        }


        if (read != "")
           messageList.Add(read); // this is where I get the error

    }

这是绑定:

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    //await Authenticate();
    Gameboard.DataContext = Game.GameDetails.Singleton;
    lstHighScores.ItemsSource = sendInfo.messageList;
}

如何在仍然绑定到我的列表视图的可观察集合的同时使错误消失?

【问题讨论】:

    标签: c# multithreading xaml windows-store-apps


    【解决方案1】:

    这解决了我的问题:

    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    () =>
        {
            // Your UI update code goes here!
        }
    );
    

    Correct way to get the CoreDispatcher in a Windows Store app

    【讨论】:

    • 仅供参考,这相当于 Android 的 runOnUiThread developer.android.com/reference/android/app/…
    • python中有没有等价物?
    • 不敢相信,这是我的确切问题,在搜索整个异常消息后,它在 Google 搜索结果中排名第一。不错!
    • @nickpick - 不是真的...这解决了 C# 中 Windows 应用程序的一个非常具体的问题。
    • 我对 C# 和 Windows 开发非常陌生,但这是一个很长的方法调用链,感觉就像是 hack。有没有更好的方法来做到这一点?
    【解决方案2】:

    尝试替换

    messageList.Add(read); 
    

    Dispatcher.Invoke((Action)(() => messageList.Add(read)));
    

    如果您是从 Window 类外部调用,请尝试:

    Application.Current.Dispatcher.Invoke((Action)(() => messageList.Add(read)));
    

    【讨论】:

    • Dispatcher 位于哪个命名空间中?它转为“System.ServiceModel.Dispatcher”,但 Invoke 不是它的一种方法。
    • 在页面(或任何 DependencyObject)中使用时,调用 Dispatcher.RunAsync(() => messageList.Add(read));在其他地方调用 Window.Current.Dispatcher.RunAsync(() => messageList.Add(read));
    【解决方案3】:

    对基于任务的异步方法稍作修改,但不会等待此处的代码。

    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    () =>
    {
        // Your UI update code goes here!
    }
    ).AsTask();
    

    此代码将等待,并允许您返回一个值:

        private async static Task<string> GetPin()
        {
            var taskCompletionSource = new TaskCompletionSource<string>();
    
            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            async () =>
            {
                var pin = await UI.GetPin();
                taskCompletionSource.SetResult(pin);
            }
            );
    
            return await taskCompletionSource.Task;
        }
    

    在 Android 上:

        private async Task<string> GetPin()
        {
            var taskCompletionSource = new TaskCompletionSource<string>();
    
            RunOnUiThread(async () =>
            {
                var pin = await UI.GetPin();
                taskCompletionSource.SetResult(pin);
            });
    
            return await taskCompletionSource.Task;
        }
    

    【讨论】:

      【解决方案4】:

      也许这不是一个“好”的做法,但它确实有效。我从 webSocket 向 mainBody 实例留言,在那里我有一个定时阅读器...

      public class C_AUTHORIZATION
      {
          public Observer3.A_MainPage_cl parentPageInstance; //еще одни экземпляр родителя
          public WebSocket x_Websocket; 
          private string payload = "";
          private DateTime nowMoment = DateTime.Now;
          public void GET_AUTHORIZED()
          {
             bitfinex_Websocket= new WebSocket("wss://*****.com/ws/2");
      
              var apiKey = "";
              var apiSecret = "";
              DateTime nowMoment = DateTime.Now;            
      
              payload = "{}";            
      
              x_Websocket.Opened += new EventHandler(websocket_Opened);                                                         
             x_Websocket.Closed += new EventHandler(websocket_Closed);  
          }
          
          void websocket_Opened(object sender, EventArgs e)
          {
              x_Websocket.Send(payload);
              parentPageInstance.F_messager(payload);
          }
          
          void websocket_Closed(object sender, EventArgs e)
          {
              parentPageInstance.F_messager("L106 websocket_Closed!");
              GET_AUTHORIZED();  
          }
         
      
      }
      
      public sealed partial class A_MainPage_cl : Page
      {      
          DispatcherTimer ChartsRedrawerTimer;
          public bool HeartBeat = true;
         
          private string Message;        
          public A_MainPage_cl()
          {
             this.InitializeComponent();
            
              ChartsRedrawerTimer = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 0, 0, 100) }; 
              ChartsRedrawerTimer.Tick += Messager_Timer;
              ChartsRedrawerTimer.Start();
      
              
          }        
               
          private void Messager_Timer(object sender, object e)
          {            
              if(Message !=null) // 
              {
                  F_WriteLine(Message);
                  Message = null; //  
      
              } 
          }
          public void F_messager(string message) // 
          { 
              Message = message; 
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-21
        • 1970-01-01
        • 1970-01-01
        • 2011-04-05
        • 2023-03-20
        相关资源
        最近更新 更多