我在xaml页面上有一个活动指示器。最初,它的IsVisible属性为false。我在页面上有一个按钮。当用户单击按钮时,它会调用Web服务来获取数据。我在调用服务之前将IsVisible属性的值更改为true,以便活动指示符开始在页面上显示,并且在成功调用服务之后,我将其值再次更改为false,以便它不再显示在页面上。
但它不起作用。我知道实际的问题。当我们调用Web服务时,UI线程会被阻塞,并且它不会显示活动指示符。 如何在调用Web服务时启用UI线程,以便活动指示器可以在页面上显示,直到我们获取数据?
答案 0 :(得分:1)
尝试将您的网络服务电话转换为async
和await
。
根据您构建内容的方式,您可能必须使用TaskCompletionSource
,如以下示例所示。
在此示例中,单击按钮时,按钮将不可见,ActivityIndicator
设置为IsRunning=True
至显示
然后使用ExecuteSomeLongTask
在函数TaskCompletionSource
中执行长时间运行的任务/ webservice。
原因是在我们的按钮点击代码中,我们有最后一行: -
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
停止 ActivityIndicator
正在运行并显示,也将按钮设置为可见状态。
如果我们没有使用TaskCompletionSource
这些行会在调用ExecuteSomeLongTask
之后立即执行,如果它是正常的异步方法/函数,则会导致ActivityIndicator
没有正在运行且按钮仍然可见。
示例: - 强>
Grid objGrid = new Grid()
{
};
ActivityIndicator objActivityIndicator1 = new ActivityIndicator();
objGrid.Children.Add(objActivityIndicator1);
Button objButton1 = new Button();
objButton1.Text = "Execute webservice call.";
objButton1.Clicked += (async (o2, e2) =>
{
objButton1.IsVisible = false;
objActivityIndicator1.IsRunning = true;
//
bool blnResult = await ExecuteSomeLongTask();
//
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
});
objGrid.Children.Add(objButton1);
return objGrid;
支持功能: -
private Task<bool> ExecuteSomeLongTask()
{
TaskCompletionSource<bool> objTaskCompletionSource1 = new TaskCompletionSource<bool>();
//
Xamarin.Forms.Device.StartTimer(new TimeSpan(0, 0, 5), new Func<bool>(() =>
{
objTaskCompletionSource1.SetResult(true);
//
return false;
}));
//
return objTaskCompletionSource1.Task;
}
答案 1 :(得分:0)
您需要以异步方式完成工作。或者换句话说:使用Asnyc & Await
确保您的UI在通话期间运行良好。
您可以在the Xamarin Docs找到更多信息。
async和await是新的C#语言功能,它们协同工作 使用任务并行库可以轻松编写线程代码 执行长时间运行的任务,而不会阻止你的主线程 应用
如果您需要进一步的帮助,请更新您的问题并发布您的代码或目前为止所尝试的内容。