我在加载给定页面时通过 WCF 加载一些数据。然后,我想在数据加载后用值填充选取器。但是,我遇到了交叉线程问题。这是代码:
protected async override void OnAppearing()
{
base.OnAppearing();
await Task.Factory.StartNew(async () => { await Initialise(); });
}
private async Task Initialise()
{
var activities = await App.XivicServicesClient.DataAccessCalls.GetRecordsAsync<ActivityDef>(null, new ConnectionInfo(null, App.XivicServicesClient.AuthToken));
var activityCodes = activities.Select(a => a.Code);
foreach (var activityCode in activityCodes)
{
ActivityPicker.Items.Add(activityCode);
}
}
在 Windows UWP 中,我收到的错误是
其他信息:应用程序调用了为不同线程编码的接口(interface)。 (HRESULT 异常:0x8001010E (RPC_E_WRONG_THREAD))
我猜我正在以一种意想不到的方式使用 OnAppearing 调用,那么我应该如何解决这个问题?当页面开始加载时,我需要进行基于任务的异步 WCF 调用。
在 iOS 上,我没有收到错误消息。
最佳答案
您的问题来自
ActivityPicker.Item.Add(activityCode);
该行只能在 UI 线程上运行。
您可以使用以下内容轻松修复此代码
protected async override void OnAppearing()
{
base.OnAppearing();
var activityCodes = await Task.Factory.StartNew(async () => { await Initialise(); });
foreach (var activityCode in activityCodes)
{
ActivityPicker.Items.Add(activityCode);
}
}
private async Task<List<string>> Initialise()
{
var activities = await App.XivicServicesClient
.DataAccessCalls
.GetRecordsAsync<ActivityDef>(null, new ConnectionInfo(null, App.XivicServicesClient.AuthToken));
return activities.Select(a => a.Code).ToList();
}
但是,我真的怀疑您“需要”使用Task.Factory.StartNew
。 GetRecordsAsync
已经是一个异步方法。 Initialise
(原文如此)中的大部分延迟很可能来自 I/O 延迟。
从另一个线程运行Initialise
只会增加运行时间,因为数据需要跨线程进行编码(marshal)以及同步。
不如尝试一下。
protected async override void OnAppearing()
{
base.OnAppearing();
var activities = await App.XivicServicesClient
.DataAccessCalls
.GetRecordsAsync<ActivityDef>(null, new ConnectionInfo(null, App.XivicServicesClient.AuthToken));
foreach (var activityCode in activities.Select(a => a.Code))
{
ActivityPicker.Items.Add(activityCode);
}
}
关于c# - 应用程序调用了为不同线程编码的接口(interface) - Xamarin Forms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41994891/