繁体   English   中英

如何按FIFO顺序序列化等待任务

[英]How can I serialize awaitable tasks in FIFO order

在我的WinRT应用程序中,UI允许用户单击列表项以开始从服务器下载预览。 当列表项处于此下载状态时,列表项模板中将显示进度条。 因此,UI不被阻止,并且用户可以自由地点击其他项目并且也开始(并发)下载。

当下载失败时(由于网络连接,让我们说),它会向UI发送一条消息。 UI通过显示MessageDialog来处理此消息:

public async void ShowError(string message)
{
    var dialog = new MessageDialog(message, "Error")
    {
        CancelCommandIndex = 0,
        DefaultCommandIndex = 0,
        Options = MessageDialogOptions.None
    };
    dialog.Commands.Add(new UICommand("OK"));

    await dialog.ShowAsync();
}

问题是,如果UI在用户解除第一个消息之前尝试显示另一条消息,则对MessageDialog.ShowAsync的调用将抛出System.UnauthorizedAccessException

我想要做的是序列化对此的访问,以便第二条消息等待第一条消息,然后显示。 第三条消息将等待第二条消息,依此类推。

所有这一切都发生在UI线程上,我不知道如何正确地做到这一点。 似乎我希望每个新的错误消息框请求将自己设置为“当前”请求,然后等待解除“上一个”请求:

public async void ShowError(string message)
{
    ...

    // *** PSEUDO CODE FOLLOWS ***

    // If a message is being displayed...
    if (_currentTask != null)
    {
        // ...wait for that task to complete
        _currentTask = NewTaskThatWaitsFor(_currentTask);
        await _currentTask;
    }
    _currentTask = dialog.ShowAsync();
    await currentTask;
}

我如何“附加”自己等待(不阻止 - 这是UI线程)我之前等待的另一个(UI线程)任务?

谁能指出我正确的方向?

我想要做的是序列化对此的访问

最简单的解决方案是SemaphoreSlim

private readonly SemaphoreSlim _dialogMutex = new SemaphoreSlim(1);
public async void ShowError(string message)
{
    await _dialogMutex.WaitAsync();
    try
    {
        var dialog = new MessageDialog(message, "Error")
        {
            CancelCommandIndex = 0,
            DefaultCommandIndex = 0,
            Options = MessageDialogOptions.None
        };
        dialog.Commands.Add(new UICommand("OK"));

        await dialog.ShowAsync();
    }
    finally
    {
        _dialogMutex.Release();
    }
}

但是,由于我已经写完了,我建议你重新考虑这一部分:

当下载失败时(由于网络连接,让我们说),它会向UI发送一条消息。 UI处理此消息...

如果您的后台任务完全不知道UI,我发现代码更清晰。 如果您正在使用消息总线,那很好(尽管我从未在需要消息总线的UI应用程序上工作过); 但是你要避免的是后台任务直接向UI发送消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM