[英]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: 这里有两个重点:
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.