如何将这个lambda表达式转换为async/await?

3
public bool Remove()
{
    var itemsToRemove = activeQueue.Where(x => x.Value.CanRemove()).ToArray();
    foreach(var item in itemsToRemove)
        activeQueue.Remove(item.Key);

    return passiveQueue.IsEmpty && activeQueue.Count == 0;
}

我希望能够将 Remove 方法改为可等待的 - public async bool Remove()。因此,唯一会阻塞的是现在返回 Task<bool>CanRemove 方法。但我不确定如何使用 await

更新:

public Task<bool> CanRemove()
{
    return Task.Run(() => {
         ...
         return false;
    });
}

“the only blocking thing is CanRemove which is now returning Task<bool>” 的意思是什么?你能展示一下 CanRemove 吗?这个方法是否涉及任何 IO 操作? - Yacoub Massad
我指的是可能会阻塞调用线程的唯一位置。它涉及一些库调用,这些调用使用同步API调用。 - Pablo
你想要移除什么?异步调用应该主要用于I/O调用(比如数据库或文件操作)。 - E. Mourits
1
我觉得这些代码似乎都不是真正的异步。你为什么需要让 Remove 成为异步操作呢?是为了不阻塞用户界面线程吗? - Yacoub Massad
@YacoubMassad:是的,它是从UI线程调用的。 - Pablo
3个回答

1

由于Remove不执行任何真正的异步工作(例如IO),而您担心不想阻塞UI线程,因此我建议您将其保持同步(不在方法内使用Task.Runasyncawait),并仅在UI事件处理程序中使用线程池线程以不阻塞UI线程。以下是一个示例:

private async void button_Clicked(object sender, EventArgs e)
{
    var result = await Task.Run(() => Remove());
    //...
}

0
一种方法是使用Task.Run()
public async Task<bool> Remove()
    {
        await Task.Run(() => {
             var itemsToRemove = activeQueue.Where(x => x.Value.CanRemove()).ToArray();
             foreach(var item in itemsToRemove)
                 activeQueue.Remove(item.Key);
         });

        return passiveQueue.IsEmpty && activeQueue.Count == 0;
    }

0

这应该可以工作。

   public async Task<bool> Remove()
    {
        for (int i = activeQueue.Count; i>=0; i++)
        {
            var aq = activeQueue[i];
            var canRemove = await aq.Value.CanRemove();
            if (canRemove)
            {
                activeQueue.RemoveAt(i);
            }                    
        }           

        return passiveQueue.IsEmpty && activeQueue.Count == 0;
    }

换句话说,无法将async/await嵌入到lambda表达式中? - Pablo
可以的(我建议阅读此内容:http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx)。 - E. Mourits

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接