【发布时间】:2020-07-06 11:36:33
【问题描述】:
我有一个带有静态 ConcurrentQueue 的类。一个类接收消息并将它们放入队列中,而该类中的另一个线程从该队列中读取它们并一次处理它们。该方法因取消令牌而中止。
清空队列的方法如下:
public async Task HandleEventsFromQueueAsync(CancellationToken ct, int pollDelay = 25)
{
while (true)
{
if (ct.IsCancellationRequested)
{
return;
}
if(messageQueue.TryDequeue(out ConsumeContext newMessage))
{
handler.Handle(newMessage);
}
try
{
await Task.Delay(pollDelay, ct).ConfigureAwait(true);
}
catch (TaskCanceledException)
{
return;
}
}
}
我的测试方法如下:
CancellationToken ct = source.Token;
Thread thread = new Thread(async () => await sut.HandleEventsFromQueueAsync(ct));
thread.Start();
EventListener.messageQueue.Enqueue(message1);
EventListener.messageQueue.Enqueue(message2);
await Task.Delay(1000);
source.Cancel(false);
mockedHandler.Verify(x => x.Handle(It.IsAny<ConsumeContext>()), Times.Exactly(2));
所以我在自己的线程中开始我的出队方法,并使用新的取消令牌。然后我将几条消息排入队列,给进程一秒钟来处理它们,然后使用 source.Cancel(false) 结束线程并使方法返回。然后我检查处理程序的调用次数是否正确。当然,我正在用不同的消息类型和不同的时间中止出队方法来测试它。
问题是,当我单独运行任何测试时,它们都成功了。但是当我尝试将它们作为一个组运行时,Visual Studio 不会运行每个测试。没有错误消息,并且它运行的测试正常成功,但运行在第二次测试后停止。
我不知道为什么会发生这种情况。我的测试在结构上都是相同的。我每次都正确中止出队线程。
什么可以迫使 Visual Studio 停止测试运行而不引发任何类型的错误?
【问题讨论】:
-
所有测试都使用相同的
CancellationTokenSource吗?不包括CancellationTokenSourcesource变量的声明。 -
源在 TestInitialize 方法中初始化。
source = new CancellationTokenSource();只是在类范围内声明。 -
那么,如果您在一个测试中取消
source.Token,您将取消所有测试,因为它是同一个令牌。每次测试都需要不同的令牌 -
@mortb 我正在为每个测试创建一个新来源和一个新令牌。只是在 TestInitialize 中声明了源(在每次测试之前运行),并且每次在测试本身中都会创建令牌,但对于每个测试来说两者都应该是新鲜的..
-
较新的代码往往不使用
Thread但Task.Run(...)*.com/a/13429164/1257728 当您编写Thread(async () => await sut.HandleEventsFromQueueAsync(ct));时调用HandleEventsFromQueueAsyncasync void 这将使您的进程崩溃,但由于代码被称为“async void”异常未被调用代码*.com/a/45448104/1257728
标签: c# multithreading visual-studio unit-testing test-runner