walterlv / BlogComments

3 stars 0 forks source link

post/task-wait-async-with-timeout #20

Open utterances-bot opened 5 years ago

utterances-bot commented 5 years ago

.NET 中让 Task 支持带超时的异步等待 - walterlv

.NET 中让 Task 支持带超时的异步等待

https://blog.walterlv.com/post/task-wait-async-with-timeout.html

LazyCuteLion commented 5 years ago
    public static async Task<T> WaitAsync<T>(this Task<T> task, int timeout)
    {
        if (await Task.Run(() => { return task.Wait(timeout); }))
            return task.Result;
        throw new TimeoutException();
    }

    public static async Task<T> WaitAsync<T>(this Task<T> task, CancellationToken token)
    {
        if (await Task.Run(() => { try { return task.Wait(-1, token); } catch { return false; } }))
            return task.Result;
        throw new TaskCanceledException();
    }
LazyCuteLion commented 5 years ago

原先本人也是使用 Task.WhenAny 来封装,后面觉得 Task.WhenAny 消耗的资源多一些(也许是错觉?): 1、目标Task优先完成,Delay还是会持续到指定时间 2、Task.WhenAny 对比 Task.Run(() => { try { return task.Wait(-1, token); } catch { return false; } }) 前者3个Task:WhenAny “观察” 其他2个(目标Task、Delay)谁先完成 后者2个Task:Run “等待” 同步方法 Wait 的完成

以上为个人理解,没有找到“相关佐证“,不知博主能否指教一二?

walterlv commented 4 years ago

@LazyCuteLion 多一个 Task 所占用的资源可比多占用一个线程少多了。在 .NET Framework 4.5 中对 Task 类进行了大幅度优化,同一时间等待 100,000 个 Task,所花费的内存空间从 23,200,000 字节优化到了 152 个字节。而线程池资源则非常宝贵,强烈不要考虑将异步方法进行同步等待。

相关资料:

Imagine waiting for 100,000 tasks at the same time. On an x64 machine that would introduce 12,000,000 bytes of overhead above and beyond the size of the tasks themselves. With .NET 4.5 that overhead has dropped to a mere 64 bytes. WaitAny likewise dropped from 23,200,000 bytes of overhead to 152 bytes.

LazyCuteLion commented 4 years ago

没看明白啊,楼主到底是赞同本人还是不赞同? 看楼主的文章,应该是不推荐在“Task.Run”中使用“Task.Wait”,这样感觉是不赞同。 然后看相关资料,原文写的标题是:Task.WaitAll, Task.WaitAny。这2个方法也是和“Wait”一样,同步执行,阻塞当前线程的啊。 糊涂了。