命名的异步Lambda函数

6
我希望能在一个函数内创建一个命名的 lambda 函数,以便之后在同一函数中多次调用它。
我曾经使用以下方式同步/无任务地完成这个过程:
Func<string, bool> pingable = (url) => return pingtest(url);

但在这种情况下,我希望将可ping函数作为任务调用,因此需要返回类型为Task。

这就是我卡住的地方。

对于以下所有内容,我都会收到编译错误:

   * Func<string, Task<bool>> pingable = (input) => { return pingtest(url); };
   * Task<bool> pingable = new Task<bool>((input) => { return pingtest(url); });

虽然我可以正常声明函数,但是我无法将其作为任务来调用:

   Func<string, bool> pingable = (input) => { return pingtest(url); };      
   var tasks = new List<Task>();
   * tasks.Add(async new Task(ping("google.de")));

我标记了所有带*的行,它们都产生了编译错误。

http://dotnetcodr.com/2014/01/17/getting-a-return-value-from-a-task-with-c/似乎提供了一个解决方案的提示,但该示例不允许未提供输入参数。(从该网址获取并简化的示例:)

Task<int> task = new Task<int>(obj => 
{
    return obj + 1;
}, 300);

如何在C#中创建和调用命名的Task lambda表达式,并且我想将其声明在函数而不是类级别。

我希望使用命名lambda表达式来多次调用它(在这种情况下为多个URL)。


鉴于您要求代码,请更新:

Func<string, Task<bool>> ping = url => Task.Run(() =>
{
    try
    {
        Ping pinger = new Ping();
        PingReply reply = pinger.Send(url);
        return reply.Status == IPStatus.Success;
    }
    catch (Exception)
    {
        return false;
    }
});

var tasks = new List<Task>();
tasks.Add(ping("andreas-reiff.de"));
tasks.Add(ping("google.de"));
Task.WaitAll(tasks.ToArray());
bool online = tasks.Select(task => ((Task<bool>)task).Result).Contains(true);

这已经使用了此处提出的解决方案。


pingtest 是什么样子的? - i3arnon
这里只是我想要插入的简写。我将在一分钟内通过编辑将其添加,并与您的解决方案结合起来。 - Andreas Reiff
1个回答

6

由于pingtest似乎是同步的,我假设您希望该方法运行在不同的线程上,因此需要使用Task.Run将工作转移到ThreadPool线程:

Func<string, Task<bool>> func = url => Task.Run(() => pingtest(url));

为了完整起见,如果 pingtestasync 的(即 pingtestAsync),您需要创建一个 async lambda 表达式:
Func<string, Task<bool>> func = async url => await pingtestAsync(url);

然而,在这种情况下,pingtestAsync已经返回了一个Task<bool>,因此没有必要再添加另一层async或者Lambda表达式。以下代码已经足够:

Func<string, Task<bool>> func = pingtestAsync;

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