如何在执行异步/等待时确保线程更改?

时间:2019-05-24 17:49:11

标签: c# .net async-await task-parallel-library

在执行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));
    }

2 个答案:

答案 0 :(得分:3)

不能。异步模式旨在简化异步(duh)代码,但要牺牲一些控制权。如果需要控制线程的创建,请使用Thread / ThreadPool。

答案 1 :(得分:3)

  

如何确保其余的异步方法(在等待之后)在其他线程上运行?

首先,确保已从线程池上下文中调用要测试的方法。一些单元测试框架确实提供了单线程上下文。在这种情况下,您需要将测试代码包装在await Task.Run(() => ...)中。

然后,模拟正在等待的方法,并确保它执行await Task.Yield();这将确保被测方法中的await将获得不完整的任务,从而使其在线程池线程上恢复。

如果要绝对确定它可以在不同线程池线程上恢复,则需要在要测试的方法上阻止单元测试方法,这样,当前的线程池线程将被阻塞,并且不用于恢复正在测试的方法。