首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取Func<Task<IResponse>>在超时检查中的结果

获取Func<Task<IResponse>>在超时检查中的结果
EN

Stack Overflow用户
提问于 2017-11-08 14:42:07
回答 2查看 76关注 0票数 0

我是异步编程的新手,所以不要做太多的事情。拜托,我需要更多的帮助。我照我在另一个问题中再次提出的那样做了。

代码语言:javascript
复制
public async Task<TResponse> SendRequestAsync<TResponse>(Func<Task<TResponse>> sendAsync)
{
        int timeout = 15;
        if (await Task.WhenAny(sendAsync, Task.Delay(timeout) == sendAsync))
        {
            return await sendAsync();
        }
        else
        {
            throw new Exception("time out!!!");
        }
}

但是我需要得到sendAsync()的结果并返回它。我也有疑问:

1)做这件事的最佳方法是什么,以及如何在Task.Delay中使用Func<Task<TResponse>>(或者可能是某种东西而不是它)?我不知道如何将Func转换为任务。

( 2)如果永续请求,则返回await sendAsync()内部。这不太好。如果不知怎么的话,我可以得到我的Func<Task<..>>的结果吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-08 15:00:12

既然您是异步编程中的新手--最好不要在一条语句中放太多东西,最好把它分开:

代码语言:javascript
复制
public async Task<TResponse> SendRequestAsync<TResponse>(Func<Task<TResponse>> sendAsync) {
    int timeout = 15;
    // here you create Task which represents ongoing request
    var sendTask = sendAsync();
    // Task which will complete after specified amount of time, in milliseconds
    // which means your timeout should be 15000 (for 15 seconds), not 15
    var delay = Task.Delay(timeout);
    // wait for any of those tasks to complete, returns task that completed first
    var taskThatCompletedFirst = await Task.WhenAny(sendTask, delay);
    if (taskThatCompletedFirst == sendTask) {
        // if that's our task and not "delay" task - we are fine
        // await it so that all exceptions if any are thrown here
        // this will _not_ cause it to execute once again
        return await sendTask;
    }
    else {
        // "delay" task completed first, which means 15 seconds has passed
        // but our request has not been completed
        throw new Exception("time out!!!");
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-11-08 14:49:46

请求被发送两次,因为sendAsync是一个Func返回任务,每个调用都不同。首先在Task.WhenAny()下调用它,然后在操作符return await sendAsync()中重复。

为了避免这个重复的调用,您应该将一个任务保存为变量,并将该任务传递给两个调用:

代码语言:javascript
复制
public async Task<TResponse> SendRequestAsync<TResponse>(Func<Task<TResponse>> sendAsync)
{
    int timeout = 15;
    var task = sendAsync();
    if (await Task.WhenAny(task, Task.Delay(timeout) == task))
    {
        return await task;
    }
    else
    {
        throw new Exception("time out!!!");
    }
}

已完成任务上的await只返回其结果,而不重新运行任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47182542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档