问题
I'm trying to use a progress dialog, while filling a datagrid, but I get the following error: "Only the original thread that created a view hierarchy can touch its views", this is my code, i hope they can help me
public async void RelacionClientesREST()
{
try
{
var dlg = ProgressDialog.Show(this, "Loading", "Cargando relación de usuarios");
ThreadPool.QueueUserWorkItem(d => {
RestClient client = new RestClient("http://portalclientewa.azurewebsites.net/api/RelacionClientes/");
var request = new RestRequest("GetData", Method.GET);
request.Timeout = 1500000;
request.RequestFormat = DataFormat.Json;
request.AddParameter("idP", Idp);
var temp = client.Execute(request).Content;
var parsedJson = JsonConvert.DeserializeObject(temp).ToString();
var lst = JsonConvert.DeserializeObject<List<ClientesProp>>(parsedJson).ToList();
dataGrid.ItemsSource = lst;
RunOnUiThread(() => {
dlg.Dismiss();
});
});
}
catch (Exception ex)
{
Toast.MakeText(this, "No hay datos registrados", ToastLength.Short).Show();
}
}
回答1:
The error is telling you the app's UI must be handled by the main thread. In your code, you are running some code on a background thread (ThreadPool.QueueUserWorkItem) that needs to be run on the UI thread (RunOnUiThread) instead.
回答2:
you cannot use dlg.Dismiss(); inside ThreadPool.QueueUserWorkItem, move it before try close sign
回答3:
why not use Task instead?
Task.Run(() => doStuff("hello world"));
It doesn't really seem a lot better, but at least it doesn't have an unused identifier.
Note: Task.Run() is .Net 4.5 or later. If you're using .Net 4 you have to do:
Task.Factory.StartNew(() => doStuff("hello world"));
Both of the above do use the thread pool.
回答4:
Only the original thread that created a view hierarchy can touch its views
As @CaPorter said, the app's UI must be handled by the main thread. There are any number of ways to get code to execute on the UI thread, you could try using Looper.MainLooper
with Handler.Post()
.
Modify your code like this :
ThreadPool.QueueUserWorkItem(d => {
...
Handler handler = new Handler(Looper.MainLooper);
Action action = () =>
{
dataGrid.ItemsSource = lst;
dlg.Dismiss();
};
handler.Post(action);
});
来源:https://stackoverflow.com/questions/46693968/error-in-xamarin-android-with-a-progress-dialog-only-the-original-thread-that-c