什么是创建永不返回的任务的最简洁方法?

时间:2017-08-30 07:03:59

标签: c# .net asynchronous async-await task

出于测试目的,我需要在接口上模拟一个Task - 返回方法,该方法返回一个从不运行延续的任务。这是我到目前为止的代码:

// FooTests.cs

[Test]
public void Foo()
{
    var yielder = Substitute.For<IYielder>();
    yielder.YieldAsync().Returns(ThreadingUtilities.NeverReturningTask);

    ...
}

// ThreadingUtilities.cs

using System.Diagnostics;
using System.Threading.Tasks;

namespace Repository.Editor.Android.UnitTests.TestInternal.Threading
{
    internal static class ThreadingUtilities
    {
        public static Task NeverReturningTask { get; } = CreateNeverReturningTask();

        private async static Task CreateNeverReturningTask()
        {
            await new StopAwaitable();
            Debug.Fail("Execution shouldn't reach here.");
        }
    }
}

// StopAwaitable.cs

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Repository.Editor.Android.UnitTests.TestInternal.Threading
{
    internal struct StopAwaitable : INotifyCompletion
    {
        public bool IsCompleted => false;

        public StopAwaitable GetAwaiter() => this;

        public void GetResult()
        {
            Debug.Fail("The continuation shouldn't have been posted!");
        }

        public void OnCompleted(Action continuation)
        {
            // Ignore the continuation.
        }
    }
}

在这里,我创建了一个自定义等待类型,只是忽略了传递给它的延续 - await new StopAwaitable()与同步方法中的return具有基本相同的效果。然后,我在async Task方法中等待它,创建一个永远不会运行延续的Task对象。

我的问题是,这是最简洁/最明确的方法吗?有没有其他方法来创建这样一个不涉及定制等待的任务,这会使人们对async的工作原理感到困惑?

2 个答案:

答案 0 :(得分:9)

我会使用await Task.Delay(-1)Task.Delay表示Task表示-1表示永远不会完成的WHEN ISNUMERIC(npx.nvcAnswer) = 1 THEN CASE WHEN ABS(CONVERT(DECIMAL(38,2),npx.nvcAnswer)) < 1 THEN CONVERT(VARCHAR,CONVERT(DECIMAL(38,2),npx.nvcAnswer)) ELSE npx.nvcAnswer END

  

完成返回任务之前等待的毫秒数,或-1无限期等待的时间。

答案 1 :(得分:6)

我希望我在这里正确地阅读这个问题......

return new System.Threading.Tasks.TaskCompletionSource<object>().Task;
  1. 返回任务完成源创建的任务。
  2. 永远不要将来源设置为完成。
  3. 永远不会调用Continuations,await将永久“阻止”。