我在我的MainActivity.cs
有以下api电话 -
public async Task DoSomething()
{
var progressDialog = ShowLoading(_instance);
await Task.Factory.StartNew(() =>
{
var objectResponse = string.Empty;
string _apiUrl = "https://my-web-service-endpoint";
var request = (HttpWebRequest)WebRequest.Create(_apiUrl);
request.Method = "GET";
using (var response = _request.HttpWebResponse(request))
{
objectResponse = _request.HttpWebResponseBody(response);
}
progressDialog.Dismiss();
});
}
我通过SliderControl.cs
中的按钮单击调用此方法 -
public void loadTestView(View view)
{
Button btnDoSomething = view.FindViewById<Button>(Resource.Id.btnDoSomething);
if (btnDoSomething != null)
{
btnDoSomething .Click += async (sender, e) =>
{
await MainActivity.GetInstance().DoSomething();
};
}
}
然而loadTestView
不是在MainActivity.cs
中调用而是在使用滑动到应用程序中的特定视图并在SliderControl.cs
中处理时调用它,它被设置为 -
public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
{
var selectedView = Resource.Layout.Locator;
if (position == 0)
{
selectedView = Resource.Layout.Main;
}
if (position == 1)
{
selectedView = Resource.Layout.TestView;
}
View view = LayoutInflater.From(container.Context).Inflate(selectedView, container, false);
container.AddView(view);
if (position == 0)
{
loadMainView(view);
}
else if (position == 1)
{
loadTestView(view);
}
return view;
}
当我设置不同的按钮时,单击MainActivity.cs
中的事件逻辑,一切都相应地工作,但是当设置按钮点击登录时,我遇到了错误 -
Only the original thread that created a view hierarchy can touch its views.
奇怪的是装载机实际上已经进入视野,但是当我进入await Task.Factory.StartNew(() =>
线时,错误命中。
我已经尝试更改线路以使用Task.Run
而不是相同的错误,并且还在Device.BeginInvokeOnMainThread
上找到了一些信息,而不管相信这是用于Xamarin Forms。我怎样才能让它发挥作用?
您应该使用UI线程来更新UI /或涉及UI的任何任务:
样本表单示例:
Device.BeginInvokeOnMainThread (() => {
label.Text = "Async operation completed";
});
John写了一些很好的例子来描述如何使用Async / Await模式。你可能想在这里阅读更多https://johnthiriet.com/configure-await/#
更新:对于Xamarin Native -
问题:
new System.Threading.Thread(new System.Threading.ThreadStart(() => {
lblTest.Text = "updated in thread";
// Doesn't work because you can't modify UILabel on background thread!
})).Start();
解:
new System.Threading.Thread(new System.Threading.ThreadStart(() => {
InvokeOnMainThread (() => {
label1.Text = "updated in thread";
// this works! We are invoking in Main thread.
});
})).Start();