简体   繁体   English

为什么单独的方法调用被认为是相同的任务?

[英]Why are separate method invocations considered the same Task?

While debugging an issue, I've found that short running tasks are considered equal. 在调试问题时,我发现短期运行任务被认为是相同的。 I'd like to know why this is, and if there is any way of preventing this behavior. 我想知道为什么会这样,如果有任何方法可以阻止这种行为。

Below, I've given a unit test (using mstest) that reproduces this behavior. 下面,我给出了一个单元测试(使用mstest)来重现这种行为。 If you uncomment the Task.Delay and introduce a delay, the test passes. 如果取消注释Task.Delay并引入延迟,则测试通过。

    private async Task successTaskFn()
    {
        //await Task.Delay(250);
        MemoryStream ms = new MemoryStream();
        using (var sw = new StreamWriter(ms))
        {
            await sw.WriteLineAsync("Line1");
            await sw.WriteLineAsync("Line2");
        }
    }

    [TestMethod]
    public void TaskIdsCheck()
    {
        var t1 = successTaskFn();
        var t2 = successTaskFn();
        var t3 = successTaskFn();

        Assert.AreNotSame(t1, t2);
        Assert.AreNotSame(t1, t3);
        Assert.AreNotSame(t2, t3);
    }

The test fails on AreNotSame, because the Task objects are considered the same. AreNotSame上的测试失败,因为Task对象被认为是相同的。

There are two important points at work here: 这里有两个重点:

  • Async methods run synchronously until the first await expression that is awaiting something that hasn't already completed. 异步方法同步运行,直到第一个await表达式等待尚未完成的内容。
  • There are optimizations to reuse tasks where possible. 在可能的情况下,可以优化重用任务。 This is only possible for completed tasks, and then only when the result is okay to cache. 这仅适用于已完成的任务,只有在结果可以缓存时才可以。 In your case you're not dealing with any tasks returning values - it's easy for "a completed task with no result" to be cached, as you only need one of them. 在你的情况下,你没有处理任何返回值的任务 - 很容易缓存“没有结果的已完成任务”,因为你只需要其中一个。

So if you have a method that does nothing asynchronous (no awaits at all) and just returns Task , that will always return the same Task . 因此,如果您有一个不执行任何异步操作的方法(根本没有等待)并且只返回Task ,那么它将始终返回相同的Task (It's no guaranteed, but that's the current behaviour.) (这不是保证,但那是当前的行为。)

If you have a method that does have awaits, it will depend on what's being awaited. 如果你有一个确实等待的方法,它将取决于正在等待的东西。 If the operation you await hasn't completed, the async machinery needs to do a complicated dance to box the state machine (the first time), schedule a continuation, and then return to the caller. 如果你等待的操作还没有完成,异步机器需要做一个复杂的舞蹈来装箱状态机(第一次),安排继续,然后返回给调用者。

In your case, you're only awaiting the result of operations on MemoryStream . 在您的情况下,您只是在等待MemoryStream上的操作结果。 There's no point in MemoryStream being asynchronous for this sort of operation, so its async methods just return a completed task - which makes it work as if it were entirely synchronous. 对于这种操作, MemoryStream没有任何异步,因此它的异步方法只返回一个已完成的任务 - 这使得它完全同步。

If you use: 如果您使用:

await Task.Yield();

that should prevent that behaviour, but I'd only do that in extreme cases. 这应该可以防止这种行为,但我只会在极端情况下这样做。 You simply shouldn't be relying on the identity of the returned task. 您根本不应该依赖返回任务的身份。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何区分相同的方法调用 - How to differentiate the same method invocations 为什么在等待它被认为是异步的同一行上调用一个方法? - Why is invoking a method on the same line as awaiting it considered asynchronous? 如果父子 class 具有同名的 static 方法,为什么会认为方法隐藏? - Why is it considered method hiding if a parent and child class have a static method with the same name? 为相同方法的两次调用设置两个不同的返回值 - Setup two different return values for two invocations of the same method 为什么静态方法有时会为单独的调用返回相同的结果? - Why Static method sometimes returns same result for separate call? 为什么在Task.Run参数中使用的外部变量被视为未分配? - Why is the external variable used in the Task.Run argument considered unassigned? 使用Moq验证具有不同参数的单独调用 - Using Moq to Validate Separate Invocations with Distinct Arguments 为什么在Java方法重载中不考虑返回类型? - Why aren't return types considered in Java method overloads? 为什么集合有单独的equals方法? - Why is there a separate equals method for sets? 在Simple Injector中对拦截的方法调用进行调用的函数 - Calling functions on intercepted method invocations in Simple Injector
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM