在调试问题时,我发现短期运行的任务被认为是平等的。我想知道为什么会这样,以及是否有任何方法可以防止这种行为。
下面,我给出了一个重现此行为的单元测试(使用mstest)。如果取消注释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);
}
在AreNotSame上测试失败,因为认为Task对象是相同的。
答案 0 :(得分:3)
这里有两个重要的要点:
因此,如果您有一个方法,它不执行任何操作(根本没有等待)并且仅返回Task
,那么该方法将始终返回相同的{{ 1}}。 (不能保证,但这是当前的行为。)
如果您有确实正在等待的方法,则取决于所等待的东西。如果您等待的操作尚未完成,则异步机制需要进行一次复杂的操作才能使状态机装箱(第一次),安排继续操作,然后返回到调用方。
就您而言,您只是在等待对Task
进行操作的结果。 MemoryStream
对于这种操作是异步的没有意义,因此它的异步方法仅返回一个完成的任务-这使它像完全同步一样工作。
如果您使用:
MemoryStream
应该可以防止这种行为,但是我只会在极端情况下这样做。您完全不应该依靠依赖返回的任务的身份。