MvvmCross命令中的异步任务未返回

时间:2017-05-13 22:01:24

标签: c# asynchronous xamarin.ios async-await mvvmcross

我正在一个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;
        }
    }
}
}

1 个答案:

答案 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和异步的上下文会导致死锁。