简体   繁体   English

如何在必要时测试实现是同步还是异步?

[英]How can I test that implementations are synchronous or asynchronous where required to be so?

I'm trying to write unit tests around a custom SynchronizationContext implementation. 我正在尝试围绕自定义SynchronizationContext实现编写单元测试。

The two important operations on this class are Send and Post , where Send invokes a delegate synchronously and Post invokes a delegate asynchronously. 此类上的两个重要操作是SendPost ,其中Send同步调用委托, Post以异步方式调用委托。

I would like to write unit tests to verify this behaviour, that the delegates were executed synchronously or asynchronously. 我想编写单元测试来验证这种行为,代理是同步还是异步执行的。 I don't want the tests to rely on delays for success cases, because it artificially prolongs the tests running (but it's reasonable to have failures cause a delay) in execution. 我不希望测试依赖于成功案例的延迟,因为它人为地延长了测试的运行时间(但是在故障导致延迟的情况下是合理的)。

Initially I have considered using Tasks to signal the execution of a delegate: 最初我考虑使用Tasks来表示委托的执行:

var tcs = new TaskCompletionSource<object>();

var context = new CustomSynchronizationContext();

context.Send((state) => tcs.SetResult(null), null);

// Task should already be completed!
Assert.IsTrue(this.tcs.Task.IsCompleted);

However, this does not ensure the delegate was not executed asynchronously very quickly before the test runner could continue. 但是,这并不能确保在测试运行器继续之前不会非常快速地异步执行委托。

How can I arrange a test around the context to ensure that Send blocks for the completion of the delegate and Post does not, but that the delegates are both invoked? 我如何安排围绕上下文中的测试,以确保Send块为代表的完成和Post没有,但代表们调用?

I believe you can achieve this using a pair of ManualResetEvents . 我相信你可以使用一对ManualResetEvents来实现这一点。 Using the code below, the slow down is only experienced if the tests failed (the numbers are pretty high and could probably be reduced safely). 使用下面的代码,只有在测试失败时才会出现减速(数字非常高并且可能安全地减少)。 The idea here is that we assert the order in which things must occur that can only happen if we block or don't block. 这里的想法是我们断言必须发生的事情的顺序,只有在我们阻止或不阻止时才会发生。

For the synchronous test: 对于同步测试:

var incall = new ManualResetEvent(false);
var unblock = new ManualResetEvent(false);
var context = new CustomSynchronizationContext();
var t = Task.Run(() => context.Send(state =>
{
    incall.Set();
    unblock.WaitOne(5000);
}, null));
Assert.IsTrue(incall.WaitOne(1000));
Assert.IsFalse(t.Wait(10));
unblock.Set();
Assert.IsTrue(t.Wait(1000));

for the Async test: 对于异步测试:

var incall = new ManualResetEvent(false);
var unblock = new ManualResetEvent(false);
var context = new CustomSynchronizationContext();
var t = Task.Run(() =>context.Post(state =>
{
    incall.Set();
    unblock.WaitOne(5000);
}, null));
Assert.IsTrue(incall.WaitOne(1000));
Assert.IsTrue(t.Wait(1000)); //This will timeout if unblock is blocking completion of the task
unblock.Set();

Incorporating my idea: 结合我的想法:

var mainThreadId = Thread.ManagedThreadId;
var sendThreadId;
context.Send((state) => sendThreadId = Thread.ManagedThreadId);
Assert.AreEqual(mainThreadId, sendThreadId);

Don't know if this actually works, you'll have to check. 不知道这是否真的有效,你必须检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 维护同步和异步实现 - Maintain both synchronous and asynchronous implementations 我可以使异步组件看起来像同步吗? - Can I make asynchronous components appear synchronous? 如何使用反应式扩展将同步轮询数据库查询转换为异步推送? - How can I turn a synchronous polling database query into an asynchronous push using reactive extensions? 我可以在为异步打开的FileStream上使用同步I / O吗? - Can I use synchronous I/O on a FileStream opened for asynchronous? 我们应该提供SmtpClient包装器的异步和同步实现吗? - Should we provide both asynchronous and synchronous implementations of SmtpClient wrapper? 我可以在一个项目中使用异步和同步套接字吗? - Can I use Asynchronous and Synchronous sockets in one project? 使同步调用异步时如何返回TaskStatus? - How do I return the TaskStatus when making a synchronous call asynchronous? 如何使同步套接字异步? - How to make synchronous socket asynchronous? 如何在一个平台具有同步代码而另一个平台具有异步代码的情况下正确实现 DependencyService - How to properly implement DependencyService where one platform has synchronous code and other has asynchronous 为什么异步代码比同步代码慢得多 - Why asynchronous code is so much slower than synchronous code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM