我在git hub上传了一些代码,可以在这里找到: https://github.com/Shaunus87/SyncTest包含我的原型代码和我的单元测试。
我基本上声明我的同步代码,挂钩事件,调用最终会调用事件的方法,并断言是否调用了事件:
bool called = false;
var testBinsToVend = GetRoboBins();
var vendHelper = new VendingHelper(null, testBinsToVend, VendType.Issue);
vendHelper.Complete += delegate () {
called = true;
};
vendHelper.DoVending();
Assert.IsTrue(called);
所有代码都是同步的(据我所知),但是如果我运行测试就会失败,如果我通过它进行调试,它会通过......
我尝试了一些事情,似乎要么a)我的代码是秘密异步并且我有竞争条件或b)在运行代码时它决定不执行一半的事件?
到底是什么?
修改 我也尝试过如下设置手动重置事件:
bool called = false;
var done = new ManualResetEvent(false);
var testBinsToVend = GetRoboBins();
var vendHelper = new VendingHelper(null, testBinsToVend, VendType.Issue);
vendHelper.Complete += delegate () {
called = true;
done.Set();
};
vendHelper.DoVending();
done.WaitOne();
Assert.IsTrue(called);
//was complete called?
Assert.AreEqual(true, vendHelper.Bins.All(x => x.State != VendState.Pending));
但由于它是一行执行,当done.WaitOne();
被命中时,测试永远不会到达Assert.IsTrue(called);
行。
答案 0 :(得分:2)
您的业务逻辑存在问题:
private CommCommand GetLastCommand(List<CommCommand> cmds, DateTime since) {
return cmds.Where(x => x.DateTime > since)
.OrderByDescending(x => x.DateTime)
.FirstOrDefault();
}
默认情况下, DateTime.Now
的分辨率约为20毫秒左右。这意味着在DateTime > since
成立之前很久就会收到您的消息。当您单步执行代码时,时间会得到调整 - Send
在原始接收后发生的时间会更长。
您无法依靠DateTime.Now
进行消息排序。它根本没有足够的准确性。如果你真的认为你可以依赖发送和接收订单的顺序(也就是说,机器在提示之前从不回复),而是用一个简单的计数器替换它。