C# Xamarin Forms:调试器离开异步方法而不等待

C# Xamarin Forms:调试器离开异步方法而不等待,c#,xamarin,xamarin.forms,async-await,C#,Xamarin,Xamarin.forms,Async Await,我刚开始使用XamarinForms,遇到了一个奇怪的问题 应用程序流程如下所示: 从一个页面(NewExpensePage.cs)中,我打开一个用于创建操作的模式(push async) 页面具有带有ViewModel(ExpenseViewModel.cs)的BindingContext 按钮命令与ViewModel类中的命令(SaveExpenseCommand)连接,该命令将调用服务(IBTService.cs)中的方法,该服务将发出HttpPost请求 页面代码隐藏: public

我刚开始使用XamarinForms,遇到了一个奇怪的问题

应用程序流程如下所示:

  • 从一个页面(NewExpensePage.cs)中,我打开一个用于创建操作的模式(push async)
  • 页面具有带有ViewModel(ExpenseViewModel.cs)的BindingContext
  • 按钮命令与ViewModel类中的命令(SaveExpenseCommand)连接,该命令将调用服务(IBTService.cs)中的方法,该服务将发出HttpPost请求
页面代码隐藏:

public partial class NewExpensePage : ContentPage
{
    private readonly ExpenseViewModel viewModel;

    public NewExpensePage(int currentGroupId)
    {
        InitializeComponent();
        viewModel = new ExpenseViewModel(currentGroupId);
        this.BindingContext = viewModel;
        // let this page know save op has completed, and the close the modal
        MessagingCenter.Subscribe<ExpenseViewModel>(this, "save-completed", async (i) => { await Navigation.PopModalAsync(); });
    }
}
最后是服务代码中的方法(IBTService.cs):

公共异步任务SaveExpense(费用模型)
{
使用(var httpClient=new httpClient())
{
httpClient.BaseAddress=新Uri(api);
httpClient.DefaultRequestHeaders.Add(“Authorization”,$“Bearer{token}”);
var dbModel=新的API费用
{
金额=型号。金额,
日期=model.Date.ToString(“dd-MM-yyyy”,CultureInfo.InvariantCulture),
ExpenseCategoryId=型号.ExpenseCategoryId,
描述=模型。描述
};
//这里:调试器运行到调用者方法(回到视图模型中),而无需等待完成
var response=wait httpClient.PostAsync(“api/Expenses/PostExpense”,新的StringContent(JsonConvert.SerializeObject(dbModel));
if(响应。IsSuccessStatusCode)
{
返回true;//临时解决方案
}
返回false;
}
}
这里的问题始于最后一个代码部分中的
var response=wait httpClient.PostAsync…
,调试器在执行这一行时立即跳出执行,而不是*等待此结果完成


任何帮助都将不胜感激

试试这个,
等待httpClient.PostAsync(“api/Expenses/postaexpense”,新的StringContent(JsonConvert.SerializeObject(dbModel),Encoding.UTF8,“application/json”)
您可能还想尝试将完整路径添加到
PostAsync
…没有区别,我甚至尝试了另一个视图的工作get请求。api还可以。我可能在mvvm处理异步/等待的方式上误用了一些基本规则……它在方法SaveExpense中返回true还是false?Await不会阻止程序,它将在任务完成时继续执行。一旦它执行这一行,默认行为是返回到viewModel并执行其他代码,一旦响应返回,它将在这一行之后执行代码,然后返回true或false。@đxěŕ和Jack Hua you都是对的。问题似乎在于http调用,而不是体系结构。特别是因为我将该调用视为一个fire-and-forget情况,因为一旦发出http调用返回控件,我就关闭了pagemodal。我修改了代码以返回错误消息和响应状态,并删除了重定向部分,这是关于模型状态验证的部分,谢谢你们两位。谢谢你们的所有输入,帮助我完成了挑战
public class ExpenseViewModel : BaseViewModel
{
    /* ... */
    public Command SaveExpenseCommand { get; set; }
    private readonly int CurrentGroupId;
    public ExpenseViewModel(int selectedGroupId)
    {
        CurrentGroupId = selectedGroupId;
        this.LoadCategoriesCommand = new Command(async () => await LoadCategories());
        this.SaveExpenseCommand = new Command(async () => await SaveExpense());
    }

    async Task SaveExpense()
    {
        Item.ExpenseCategoryId = SelectedCategory.Id;
        await IBTService.SaveExpense(Item);
        MessagingCenter.Send(this, "save-completed");
    }
}
    public async Task<bool> SaveExpense(Expense model)
    {
        using (var httpClient = new HttpClient())
        {
            httpClient.BaseAddress = new Uri(api);
            httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");

            var dbModel = new ApiExpense
            {
                Amount = model.Amount,
                Date = model.Date.ToString("dd-MM-yyyy", CultureInfo.InvariantCulture),
                ExpenseCategoryId = model.ExpenseCategoryId,
                Description = model.Description
            };
            // HERE: Debugger runs out to caller method (back in view model) without waiting for this to complete
            var response = await httpClient.PostAsync("api/Expenses/PostExpense", new StringContent(JsonConvert.SerializeObject(dbModel)));
            if (response.IsSuccessStatusCode)
            {
                return true; //temp solution
            }

            return false;
        }
    }