C#에서 TPL을 사용하여 몇 가지 테스트를 해본 결과 스레드가 생성되는 방식과 정확히 새로운 스레드가 시작될 때를 더 잘 이해할 수있었습니다.C#에서 TPL을 사용하여 async/await/result와 불일치가 발생했습니다.
아래 테스트에서 첫 번째 것은 async/await
을 사용하지 않고 예상 한대로 동작하며 예상 한 값을 항상 반환합니다. 그러나 async/await
을 사용한 마지막 2 개의 테스트는 매우 일치하지 않습니다. 내 테스트에서
, 나는 다음과 같은 가정을 만들어 :
GetThreadIdInstant
인해 작업 인 completetd에 동일한 스레드에서 반환.GetThreadIdDelayed
은 지연이 즉시 반환되지 않기 때문에 다른 스레드에서 반환됩니다.GetThreadIdForcedNew
은Task.Run()
을 사용하기 때문에 다른 스레드에서 반환됩니다.async/await
를 사용하는 경우
항상 true를 작업에 .Result
를 사용하는 경우 위의 가정에 해당하는 이유에 대한 설명이 있는가, 그러나?
편집 : "일관성이없는"테스트의 명확화 : 따라서 async/await
을 사용한 마지막 두 테스트에서 나는 여전히 .Result
을 사용하여 첫 번째 테스트와 동일한 결과를 줄 것으로 예상했지만 이는 사실이 아닙니다. 그러나 내가 루프 안에 for
루프의 코드가있는 이유는 일부 반복 작업이 작동하고 나중에 내 Assert
문이 실패합니다. 내가 "일관성이 없다"라는 말을 사용하는 이유는 테스트를 계속 실행하는 b/c이고 디버깅과 디버깅을 번갈아 수행하는 것에서 때때로 통과하고 때로는 실패하게 만드는 것입니다.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Parallels.Tests
{
[TestClass]
public class GetterTests
{
//this test always succeeds
[TestMethod]
public void ResultTest()
{
for (var i = 0; i < 500; i++)
{
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
var instantThreadId = ThreadGetter.GetThreadIdInstant().Result;
var delayedThreadId = ThreadGetter.GetThreadIdDelayed().Result;
var forcedNewThreadId = ThreadGetter.GetThreadIdForcedNew().Result;
Assert.AreEqual(currentThreadId, instantThreadId);
Assert.AreNotEqual(currentThreadId, delayedThreadId);
Assert.AreNotEqual(currentThreadId, forcedNewThreadId);
}
}
//mixed results
[TestMethod]
public async Task AwaitDelayedTest()
{
for (var i = 0; i < 500; i++)
{
try
{
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
var delayedThreadId = await ThreadGetter.GetThreadIdDelayed();
Assert.AreNotEqual(currentThreadId, delayedThreadId);
}
catch (Exception ex)
{
throw new Exception($"failed at iteration: {i}", ex);
}
}
}
//mixed results
[TestMethod]
public async Task AwaitForcedNewTest()
{
for (var i = 0; i < 500; i++)
{
try
{
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
var forcedNewThreadId = await ThreadGetter.GetThreadIdForcedNew();
Assert.AreNotEqual(currentThreadId, forcedNewThreadId);
}
catch (Exception ex)
{
throw new Exception($"failed at iteration: {i}", ex);
}
}
}
}
public static class ThreadGetter
{
public static async Task<int> GetThreadIdInstant() => Thread.CurrentThread.ManagedThreadId;
public static async Task<int> GetThreadIdDelayed()
{
await Task.Delay(1);
return Thread.CurrentThread.ManagedThreadId;
}
public static async Task<int> GetThreadIdForcedNew() => await Task.Run(() => Thread.CurrentThread.ManagedThreadId);
}
}
"매우 모순되는"의미를 정확하게 설명하면 도움이됩니다. 결과가 무엇인지 알지 못하면 결과를 설명하기가 어렵습니다. –
또한 [TPL] (https://msdn.microsoft.com/en-us/library/hh873175(v=vs.110) .aspx)이 아니라 [TPL] (https://msdn.microsoft .com/en-us/library/dd460717 (v = vs.110) .aspx). 귀하의 질문에 TPL에만 해당되는 내용은 없습니다. – sellotape
"일관성없는"의미의 내용에 대해 더 많은 설명을하려고했습니다. – Sharpiro