当前位置:  开发笔记 > 编程语言 > 正文

如何使异步方法对任务类型通用

如何解决《如何使异步方法对任务类型通用》经验,为你挑选了1个好方法。

我的问题从表面上看与使用泛型类型作为异步方法的返回类型非常相似。但是,他没有现实世界的使用场景,因此可以说的是您无法做到这一点。我从乔恩·斯凯特(Jon Skeet)对这个问题的回答以及博客文章中了解到,为什么异步方法必须返回Task?为什么不支持它。这篇文章讨论了解决方法,但是没有一个适用于我的用例。

我的问题是,鉴于我正在尝试做的事情,解决语言限制的最佳方法是什么?

在生产代码中,我们有一个retry方法,该方法采用a Func并返回Task。然后,我们还需要能够重试TaskT>功能。因此,我们将重试方法更改为(略有简化):

public static async T Retry(Func action) where T : Task
{
    for (var i = 0; ; i++)
    {
        try
        {
            return await action();
        }
        catch (Exception)
        {
            if (i >= 3)
                throw;
        }       
    }
}

编译器当然会报告错误“异步方法的返回类型必须为空,任务或任务”。我可以做Retry的工作既TaskTask不写入方法的两个副本?



1> Jon Skeet..:

不,异步只是不支持。伪造的最简单选择是:

public static async Task Retry(Func> action)
{
    for (var i = 0; ; i++)
    {
        try
        {
            return await action();
        }
        catch (Exception)
        {
            if (i >= 3)
                throw;
        }       
    }
}

public static async Task Retry(Func action)
{
    Func> d = async () => { await action(); return 0; };
    await Retry(d);
}

这不涉及代码重复,但是当您调用非通用版本时,您确实会面临很多彼此重叠的任务层。您可以将后者更改为:

public static Task Retry(Func action)
{
    Func> d = async () => { await action(); return 0; };
    return Retry(d);
}

然后,它实际上会返回一个Task,但是假设您的呼叫者不在乎,它确实节省了一部分重定向。

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有