接受Func <t>的简单超时方法未在等待

时间:2019-03-07 12:46:28

标签: c# asynchronous async-await

我正在尝试创建一个简单的可重用的超时方法,该方法是完全异步的。由于某些原因,我的超时方法没有被等待,我为为什么而感到困惑。

    [Fact]
    public async void TestTimeOut()
    {
        Stopwatch sw = Stopwatch.StartNew();
        var Thrown = false;
        try
        {
            await TimeOut(() => Task.Delay(5000), TimeSpan.FromMilliseconds(1000));
        }
        catch(OperationCanceledException ex)
        {
            //** Never Hit
            Thrown = true;
        }
        sw.Stop();

        Assert.True(sw.Elapsed >= TimeSpan.FromMilliseconds(1000)); //** fails nothing is awaited, executes in less than 40ms

        Assert.True(Thrown); //** Fails
    }

    private async Task<T> TimeOut<T>(Func<T> method, TimeSpan timeOut)
    {
        using (var ctsForTask = new CancellationTokenSource())
        {
            var taskTimeOut = Task.Delay(timeOut);
            Task<T> task = Task.Run(() => method(), ctsForTask.Token);
            if (task != await Task.WhenAny(task, taskTimeOut))
            {
                ctsForTask.Cancel();
                throw new OperationCanceledException(ctsForTask.Token);
            }
            return task.Result;
        }
    }

2 个答案:

答案 0 :(得分:5)

Timeout正在等待,但() => Task.Delay(5000) lambda尚未等待。由于Task.Run不知道TTask,因此它会立即返回。改用Func<Task<T>>Func<Task>

答案 1 :(得分:0)

使用Func<Task<T>> method参数并等待timout方法中的结果