在C#中跨越android活动导航等待TaskCompletionSource

时间:2017-02-26 21:09:32

标签: c# android xamarin xamarin.android mvvmcross

我试图创建一个可以收集用户输入的等待方法,我可以从我的viewmodel / core调用。 在android上我想要一个带有输入字段和" OK" -button的新活动。一旦用户点击OK,就应该关闭用户输入活动,并且该方法应该完成。存储和管理数据不是问题,但实际呈现用户输入活动是。

我有一个小项目,其中有一个等待此方法的按钮。我可以看到活动过渡动画,但MultiChoiceActivity的(非常简单的)布局实际上从未显示过。

    //### ViewModel
    public MvxAsyncCommand ShowListWithTitleCommand
    {
        get
        {
            _showListWithTitleCommand = _showListWithTitleCommand ?? new MvxAsyncCommand(() => DoShowListCommandAsync("Alt title"));
            return _showListWithTitleCommand;
        }
    }

    private async Task DoShowListCommandAsync(string title)
    {
        var bundle = new DialogServiceMultiItemsBundle(title, _allItems, _checkedItems.ToArray());
        var result = await _dialog.ShowMultipleChoice(bundle);
    }

    //### Awaitable method
    public Task<List<int>> ShowMultipleChoice(DialogServiceMultiItemsBundle bundle)
    {
        LastTcs = new TaskCompletionSource<List<int>>();
        LastBundle = bundle;

        CurrentContext.RunOnUiThread(() => {
            CurrentContext.StartActivity(typeof(MultiChoiceActivity));
        });

        return LastTcs.Task;
    }

我应该如何在活动过渡期间等待此方法?添加async-await到该方法似乎没有任何区别。

我没有成功尝试过Task.Run()来取消UI线程(与上面相同的行为):

return await Task.Run<List<int>>(async () => { return await LastTcs.Task; });

1 个答案:

答案 0 :(得分:0)

我不认为我曾经以这种方式开始过度活动 - 我不确定你是否正确地启动它。这是我一直以来所做的,也许这是你的麻烦的关键?

var intent = new Intent (this, typeof(MultiChoiceActivity));
StartActivity (intent);

或者也许(因为它看起来像是在MVVM上下文中):

var intent = new Intent (CurrentContext, typeof(MultiChoiceActivity));
CurrentContext.StartActivity (intent);

这里的关键区别是使用显式Intent来启动活动。

需要考虑的其他事项:

我非常确定您在开始活动时不需要使用RunOnUiThread()

确保在活动启动后测试只需点击设备上的“后退”按钮 - 我不确定那里的行为是否符合预期。这可能永远不会让活动有机会调用SetResult()SetException(),除非您对其进行编码以处理该情况。同样,请确保在加载或卸载该活动时抛出异常进行测试。你不想要的是在等待僵尸任务的情况下回到你的主要活动。