我正在一个Xamarin PCL项目中使用MvvMCross构建一个小项目,并且遇到一个异步任务问题,我在一个绑定到按钮的命令中调用它。
我有一个虚假的网络服务,我只需要调用Task.Delay(3000)。当这个过程达到这一点时,它只是坐着而什么都不做。
我最初使用.wait()调用进行了命令调用,但是在某处读取这是一个阻塞调用,并且无法使用" async / wait"
有人可以提供帮助,并且可以给我一个提示,告诉我命令绑定在哪里出错吗?
https://bitbucket.org/johncogan/exevaxamarinapp是公共git repo,具体命令是
public ICommand SaveProfile
在ProfileViewModel.cs文件中。
具体代码是:
public ICommand SaveProfile
{
get
{
return new MvxCommand(() =>
{
if (_profile.IsValidData())
{
// Wait for task to compelte, do UI updates here
// TODO Throbber / Spinner
EnumWebServiceResult taskResult;
Mvx.Resolve<IProfileWebService>().SendProfileToServer(_profile).Wait();
if(_profileWebService.getLastResponseResult() == true){
taskResult = EnumWebServiceResult.SUCCESS;
}else{
taskResult = EnumWebServiceResult.FAILED_UNKNOWN;
}
//_profileWebService.SendProfileToServer(_profile).Wait();
// Close(this);
}
});
}
}
Web服务类()是:
using System;
using System.Threading.Tasks;
using ExevaXamarinApp.Models;
namespace ExevaXamarinApp.Services
{
public class FakeProfileWebService : IProfileWebService
{
public int _delayPeriod { get; private set; }
public bool? lastResult;
/// <summary>
/// Initializes a new instance of the <see cref="T:ExevaXamarinApp.Enumerations.FakeProfileWebService"/> class.
/// </summary>
/// 3 second delay to simulate a remote request
public FakeProfileWebService()
{
_delayPeriod = 3000;
lastResult = null;
}
private Task Sleep()
{
return Task.Delay(3000);
}
public bool? getLastResponseResult(){
return lastResult;
}
/// <summary>
/// Sends the profile to server asynchronously
/// </summary>
/// <returns>EnumWebServiceResultFlag value</returns>
/// <param name="profileObject">Profile model object</param>
public async Task SendProfileToServer(Profile profileObject)
{
// Validate arguments before attempting to use web serivce
if (profileObject.IsValidData())
{
// TODO: Return ENUM FLAG that represents the state of the result
await Sleep();
lastResult = true;
}else{
lastResult = false;
}
}
}
}
答案 0 :(得分:2)
请试试这个:
public ICommand SaveProfile
{
get
{
return new MvxCommand(async () => // async added
{
if (_profile.IsValidData())
{
// Wait for task to compelte, do UI updates here
// TODO Throbber / Spinner
EnumWebServiceResult taskResult;
await Mvx.Resolve<IProfileWebService>().SendProfileToServer(_profile).ConfigureAwait(false); // await, confi.. added
if(_profileWebService.getLastResponseResult() == true){
taskResult = EnumWebServiceResult.SUCCESS;
}else{
taskResult = EnumWebServiceResult.FAILED_UNKNOWN;
}
//_profileWebService.SendProfileToServer(_profile).Wait();
// Close(this);
}
});
}
}
private async Task Sleep() // async added
{
return await Task.Delay(3000).ConfigureAwait(false); // await, confi... added
}
public async Task SendProfileToServer(Profile profileObject)
{
// Validate arguments before attempting to use web serivce
if (profileObject.IsValidData())
{
// TODO: Return ENUM FLAG that represents the state of the result
await Sleep().ConfigureAwait(false); // await, confi... added
lastResult = true;
}else{
lastResult = false;
}
}
问题是,来自UI和异步的上下文会导致死锁。