如何确保在执行 async/await 时线程发生变化?
How to ensure a thread change when doing async/await?
在执行 await
时,Task
可能会也可能不会在同一个线程上执行。通常,我们只需要将这一事实纳入设计考虑即可。但我想专门针对线程更改场景进行测试 - 如何确保异步方法的其余部分(等待之后)在不同的线程上 运行?
可能的解决方案:
[Test]
public void TestForThreadChange()
{
int threadIdBefore, threadIdAfter = 0;
async Task AsyncFunction()
{
Console.WriteLine($"before - {threadIdBefore = Thread.CurrentThread.ManagedThreadId}");
await Task.Yield();
Console.WriteLine($"after - {threadIdAfter = Thread.CurrentThread.ManagedThreadId}");
}
AsyncFunction().Wait();
Assert.That(threadIdBefore, Is.Not.EqualTo(threadIdAfter));
}
你不能。异步模式旨在以牺牲某些控制为代价来简化异步(duh)代码。如果需要控制线程创建,使用Thread/ThreadPool.
how do I ensure the rest of the async method (after await) is run on a different thread?
首先,确保您已从 thread-pool 上下文中调用被测试的方法。一些单元测试框架确实提供了 single-threaded 上下文。如果是这种情况,您需要将测试代码包装在 await Task.Run(() => ...)
.
中
然后,模拟正在等待的方法并确保它执行await Task.Yield()
;这将确保被测方法中的 await
将获得未完成的任务,导致它在线程池线程上恢复。
如果您想绝对确定它会在不同的线程池线程上恢复,您需要阻塞您的单元在被测方法上测试方法,使当前线程池线程阻塞,不用于恢复被测方法。
在执行 await
时,Task
可能会也可能不会在同一个线程上执行。通常,我们只需要将这一事实纳入设计考虑即可。但我想专门针对线程更改场景进行测试 - 如何确保异步方法的其余部分(等待之后)在不同的线程上 运行?
可能的解决方案:
[Test]
public void TestForThreadChange()
{
int threadIdBefore, threadIdAfter = 0;
async Task AsyncFunction()
{
Console.WriteLine($"before - {threadIdBefore = Thread.CurrentThread.ManagedThreadId}");
await Task.Yield();
Console.WriteLine($"after - {threadIdAfter = Thread.CurrentThread.ManagedThreadId}");
}
AsyncFunction().Wait();
Assert.That(threadIdBefore, Is.Not.EqualTo(threadIdAfter));
}
你不能。异步模式旨在以牺牲某些控制为代价来简化异步(duh)代码。如果需要控制线程创建,使用Thread/ThreadPool.
how do I ensure the rest of the async method (after await) is run on a different thread?
首先,确保您已从 thread-pool 上下文中调用被测试的方法。一些单元测试框架确实提供了 single-threaded 上下文。如果是这种情况,您需要将测试代码包装在 await Task.Run(() => ...)
.
然后,模拟正在等待的方法并确保它执行await Task.Yield()
;这将确保被测方法中的 await
将获得未完成的任务,导致它在线程池线程上恢复。
如果您想绝对确定它会在不同的线程池线程上恢复,您需要阻塞您的单元在被测方法上测试方法,使当前线程池线程阻塞,不用于恢复被测方法。