【发布时间】:2017-04-15 05:42:21
【问题描述】:
我有一个实现INotifyPropertyChanged 的简单类,我在另一个线程上调用属性更改,我很难让FluentAsserts 看到propertyChanged 被调用。如果我在 async Task 方法中使用 Task.Delay 似乎不会发生这种情况。但如果我只是让线程休眠,它就可以了。
SimpleNotify 类:
namespace FluentAssertPropertyThreads
{
class SimpleNotify : System.ComponentModel.INotifyPropertyChanged
{
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private void onChange(string name)
{
this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(name));
}
private int count = 0;
public int Count
{
get
{
return this.count;
}
set
{
if (this.count != value)
{
this.count = value;
this.onChange(nameof(this.Count));
}
}
}
}
}
这是我的单元测试:
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FluentAssertPropertyThreads
{
[TestClass]
public class UnitTest1
{
private SimpleNotify simpleNotify;
private int notifyCount;
private void bumpCount()
{
this.simpleNotify.Count++;
}
private void SimpleNotify_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
SimpleNotify simpleNotify = sender as SimpleNotify;
if (simpleNotify == null)
{
throw new ArgumentNullException(nameof(sender), "sender should be " + nameof(SimpleNotify));
}
if (e.PropertyName.Equals(nameof(SimpleNotify.Count), StringComparison.InvariantCultureIgnoreCase))
{
this.notifyCount++;
}
}
[TestInitialize]
public void TestSetup()
{
this.notifyCount = 0;
this.simpleNotify = new SimpleNotify();
this.simpleNotify.PropertyChanged += SimpleNotify_PropertyChanged;
this.simpleNotify.MonitorEvents();
Thread thread = new Thread(this.bumpCount)
{
IsBackground = true,
Name = @"My Background Thread",
Priority = ThreadPriority.Normal
};
thread.Start();
}
[TestMethod]
public async Task TestMethod1()
{
await Task.Delay(100);
this.notifyCount.Should().Be(1); //this passes, so I know that my notification has be executed.
this.simpleNotify.ShouldRaisePropertyChangeFor(x => x.Count); //but this fails, saying that I need to be monitoring the events (which I am above)
}
[TestMethod]
public void TestMethod2()
{
Thread.Sleep(100);
this.notifyCount.Should().Be(1); //this passes, so I know that my notification has be executed.
this.simpleNotify.ShouldRaisePropertyChangeFor(x => x.Count); //this passes as I expected
}
}
}
确切的错误是:
System.InvalidOperationException:对象没有被监视事件或已被垃圾收集。使用 MonitorEvents() 扩展方法开始监控事件。
我不明白 MonitorEvents 会在意我使用 await 还是 Thread.Sleep。我错过了什么?我知道await 离开该方法并返回,而Thread.Sleep 没有。
所以当它在等待期间离开TestMethod1 时,它正在处理FluentAsserts 用来跟踪属性的对象?可以吗?应该是?
【问题讨论】:
标签: c# multithreading thread-safety async-await fluent-assertions