C#のTPLでいくつかのテストを行っています。C#のTPLを使用したasync/await/resultの不一致
以下のテストでは、最初のものは、async/await
を使用せず、期待どおりの動作をし、常に期待した値を返します。しかし、async/await
を使った最後の2つのテストは非常に矛盾しています。私のテストで
、私は次のような仮定をした:
GetThreadIdInstant
が原因タスクであることcompletetdに同じスレッドに返します。GetThreadIdDelayed
は、遅延が即座に戻ってこないため、別のスレッドで返されます。GetThreadIdForcedNew
は、Task.Run()
の使用のために別のスレッドで返されます。
async/await
を使用している場合があるタスクに.Result
を使用する時には、上記の仮定が真である理由の説明が、一貫して真実ではないですか? を使用している最後の2つのテストでは、.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/ja-us/library/dd460717(v = vs.110).aspx)。あなたの質問にはTPL特有のものはありません。 – sellotape
私は「矛盾している」という意味をもっと明確にしようとしました。 – Sharpiro