Xamarin Forms - 在继续之前等待异步方法完成
Xamarin Forms - Wait for async method to complete before continuing
在我的 Xamarin.Forms 应用程序中,我有打开弹出页面的代码(使用 Rg Popups 插件),它执行对我的 API 的调用,在数据库中插入一些数据。
我需要打开弹出窗口的异步调用以等待弹出页面的任务完成,然后执行另一个异步调用来更新当前视图中的 ListView。
但是,弹出窗口的异步任务不会等到弹出窗口完成工作才能继续下一个任务,这意味着视图不会更新
这是有问题的代码:
bool jobTask = await CloseCurOpenJob();
if (jobTask == true)
{
await FillDocuments();
}
await Navigation.PushPopupAsync(new JobClosePopupPage(Base.activeJobId));
return true;
private async Task<string> FillDocuments()
{
HttpClient client = new HttpClient();
try
{
if (jobid > 0)
{
var response = await client.GetStringAsync(myApiUri);
var DocumentsList = JsonConvert.DeserializeObject<List<DocumentHeader>>(response);
Documents = new ObservableCollection<DocumentHeader>((IEnumerable<DocumentHeader>)DocumentsList);
DocumentCount = Documents.Count();
DocumentSubtotal = Documents.Sum(instance => instance.TotalQuantity);
}
return "OK";
}
catch (Exception e)
{
return e.Message;
}
}
这是弹出页面的 ViewModel 中的代码
private async Task<bool> CloseJob(int jobid)
{
HttpClient client = new HttpClient();
try
{
var response = await client.PostAsync(myAPIUri);
string responseString = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
await CheckGetOpenJob();
return true;
}
else
{
await Application.Current.MainPage.DisplayAlert(Base.applicationTitle, responseString, "OK");
return false;
}
}
catch (Exception e)
{
await Application.Current.MainPage.DisplayAlert(Base.applicationTitle, e.Message, "OK");
return false;
}
finally
{
await Navigation.PopPopupAsync();
}
}
我已经尝试使用 Task.Run 和 Task.Delay 但结果仍然相同 - FillDocuments 方法在弹出窗口显示后运行,而不是在弹出窗口关闭后运行。
Task.Wait()
和 Task.Result
将使程序等待异步任务方法完成。
如果CloseCurOpenJob()
像public async Task<bool> CloseCurOpenJob(){}
你可以试试下面的代码:
// Both are applicable to simple Tasks:
bool jobTask = CloseCurOpenJob().Result;
或
Task<bool> result = CloseCurOpenJob();
result.Wait();
bool jobTask = result.Result;
根据您的描述,您希望在弹出窗口显示时对其进行更新。但是你说用.Wait()方法弹窗不显示
一般来说,这不应该发生。但是你可以尝试使用 Thread.Sleep() 例如:
bool jobTask = await CloseCurOpenJob();
Thread.Sleep(1000); //make the thread to wait for 1s and the async task usually completes in 1s
if (jobTask == true)
{
await FillDocuments();
}
但是这种方式似乎不太优雅,你可以post关于CloseCurOpenJob()
方法的代码。另外,如果CloseCurOpenJob()
是public async bool CloseCurOpenJob()
,可以不用await让线程等待。如
bool jobTask = CloseCurOpenJob();
我想分享一些我发现的东西:
问题不在于代码,而在于它的流程。
也就是说,我需要一个页面来关闭弹出窗口,而另一个页面正在工作。
我认为我找到的解决方案 - 尚未经过测试 - 如下:
显示弹出窗口
在显示弹出窗口后在主页面的线程中进行处理 - 因为它是异步的,代码将继续执行任务。
在主页代码中关闭弹出窗口(使用 Rg 插件的 PopAllPopup 方法)。
所以...
bool jobTask = await CloseCurOpenJob();
if (jobTask == true)
{
await FillDocuments();
}
会变成
await Navigation.PushPopupAsync(new JobClosePopupPage(Base.activeJobId));
bool jobTask = MethodThatProcessesTheData().Result;
await Navigation.PopAllPopupAsync();
我认为这应该是这样的...
在我的 Xamarin.Forms 应用程序中,我有打开弹出页面的代码(使用 Rg Popups 插件),它执行对我的 API 的调用,在数据库中插入一些数据。 我需要打开弹出窗口的异步调用以等待弹出页面的任务完成,然后执行另一个异步调用来更新当前视图中的 ListView。
但是,弹出窗口的异步任务不会等到弹出窗口完成工作才能继续下一个任务,这意味着视图不会更新
这是有问题的代码:
bool jobTask = await CloseCurOpenJob();
if (jobTask == true)
{
await FillDocuments();
}
await Navigation.PushPopupAsync(new JobClosePopupPage(Base.activeJobId));
return true;
private async Task<string> FillDocuments()
{
HttpClient client = new HttpClient();
try
{
if (jobid > 0)
{
var response = await client.GetStringAsync(myApiUri);
var DocumentsList = JsonConvert.DeserializeObject<List<DocumentHeader>>(response);
Documents = new ObservableCollection<DocumentHeader>((IEnumerable<DocumentHeader>)DocumentsList);
DocumentCount = Documents.Count();
DocumentSubtotal = Documents.Sum(instance => instance.TotalQuantity);
}
return "OK";
}
catch (Exception e)
{
return e.Message;
}
}
这是弹出页面的 ViewModel 中的代码
private async Task<bool> CloseJob(int jobid)
{
HttpClient client = new HttpClient();
try
{
var response = await client.PostAsync(myAPIUri);
string responseString = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
await CheckGetOpenJob();
return true;
}
else
{
await Application.Current.MainPage.DisplayAlert(Base.applicationTitle, responseString, "OK");
return false;
}
}
catch (Exception e)
{
await Application.Current.MainPage.DisplayAlert(Base.applicationTitle, e.Message, "OK");
return false;
}
finally
{
await Navigation.PopPopupAsync();
}
}
我已经尝试使用 Task.Run 和 Task.Delay 但结果仍然相同 - FillDocuments 方法在弹出窗口显示后运行,而不是在弹出窗口关闭后运行。
Task.Wait()
和 Task.Result
将使程序等待异步任务方法完成。
如果CloseCurOpenJob()
像public async Task<bool> CloseCurOpenJob(){}
你可以试试下面的代码:
// Both are applicable to simple Tasks:
bool jobTask = CloseCurOpenJob().Result;
或
Task<bool> result = CloseCurOpenJob();
result.Wait();
bool jobTask = result.Result;
根据您的描述,您希望在弹出窗口显示时对其进行更新。但是你说用.Wait()方法弹窗不显示
一般来说,这不应该发生。但是你可以尝试使用 Thread.Sleep() 例如:
bool jobTask = await CloseCurOpenJob();
Thread.Sleep(1000); //make the thread to wait for 1s and the async task usually completes in 1s
if (jobTask == true)
{
await FillDocuments();
}
但是这种方式似乎不太优雅,你可以post关于CloseCurOpenJob()
方法的代码。另外,如果CloseCurOpenJob()
是public async bool CloseCurOpenJob()
,可以不用await让线程等待。如
bool jobTask = CloseCurOpenJob();
我想分享一些我发现的东西:
问题不在于代码,而在于它的流程。 也就是说,我需要一个页面来关闭弹出窗口,而另一个页面正在工作。
我认为我找到的解决方案 - 尚未经过测试 - 如下:
显示弹出窗口 在显示弹出窗口后在主页面的线程中进行处理 - 因为它是异步的,代码将继续执行任务。 在主页代码中关闭弹出窗口(使用 Rg 插件的 PopAllPopup 方法)。
所以...
bool jobTask = await CloseCurOpenJob();
if (jobTask == true)
{
await FillDocuments();
}
会变成
await Navigation.PushPopupAsync(new JobClosePopupPage(Base.activeJobId));
bool jobTask = MethodThatProcessesTheData().Result;
await Navigation.PopAllPopupAsync();
我认为这应该是这样的...