所以,首先我已经阅读了大量关于这个特定问题的线程,但我仍然不知道如何解决它。基本上,我正在尝试与 websocket 通信并将收到的消息存储在绑定到 listview 的可观察集合中。我知道我从套接字正确返回响应,但是当它尝试将其添加到可观察集合时,它给了我以下错误:
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;
}
如何使错误消失,同时仍绑定到列表视图的可观察集合?
这解决了我的问题:
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
}
);
在 Windows 应用商店应用中获取 CoreDispatcher 的正确方法
尝试替换
messageList.Add(read);
跟
Dispatcher.Invoke((Action)(() => messageList.Add(read)));
如果从 Window 类外部调用,请尝试:
Application.Current.Dispatcher.Invoke((Action)(() => messageList.Add(read)));
对基于任务的异步方法稍作修改,但此处的代码不会被等待。
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;
}
在安卓上:
private async Task<string> GetPin()
{
var taskCompletionSource = new TaskCompletionSource<string>();
RunOnUiThread(async () =>
{
var pin = await UI.GetPin();
taskCompletionSource.SetResult(pin);
});
return await taskCompletionSource.Task;
}
在 Xamarin 中,我通过使用:
Device.BeginInvokeOnMainThread(() => {
// code goes here
});
Maby 这不是一个"好"的做法,但它有效。我从 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;
}