我有一个简单的窗口,其中Button和TextBox名为 SimpleText
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonClicked(object sender, RoutedEventArgs e)
{
TestMe();
}
public Task TestMe()
{
return Task.Factory.StartNew(() =>
{
for (int i = 0; i <= 11000; i++)
{
var text = i;
SimpleText.Dispatcher.Invoke(() => SimpleText.Text = text.ToString(CultureInfo.InvariantCulture));
}
});
}
}
当我点击按钮程序exectute ButtonClicked 时 然后我决定测试这段代码
[TestMethod]
public void TestMethod1()
{
var mainWindow = new MainWindow();
Assert.IsNotNull(mainWindow);
var task = mainWindow.TestMe();
DispatcherUtil.DoEvents();
Assert.AreEqual(mainWindow.SimpleText.Text, "11000");
}
DispatcherUtil 是帮助程序类。帮我从调度员队列中做事件
public static class DispatcherUtil
{
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void DoEvents()
{
var frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}
private static object ExitFrame(object frame)
{
((DispatcherFrame)frame).Continue = false;
return null;
}
}
我的测试下降了文本框值“34”。有时测试值为“56”。因此我需要等待所有队列完成。我怎么能这样做?
如果我等了task.Wait()我的测试正在运行而没有结束,从未完成
答案 0 :(得分:0)
好的我知道这里发生了什么:你的测试方法和SimpleText.Dispatcher
在同一个线程上运行,这意味着如果你调用SimpleText.Dispatcher.Invoke
然后task.Wait()
你有一个经典的死锁:
[TestMethod]
public void TestMethod1()
{
var mainWindow = new MainWindow();
Assert.IsNotNull(mainWindow);
var task = mainWindow.TestMe();
DispatcherUtil.DoEvents(); // synchronously invokes onto this thread
task.Wait(); // blocks this thread so DoEvents is blocked (I've added this).
Assert.AreEqual(mainWindow.SimpleText.Text, "11000");
}
如果您现在将Invoke
更改为BeginInvoke
,则通话将不再同步,一切正常。
public Task TestMe()
{
return Task.Factory.StartNew(() =>
{
for (int i = 0; i <= 11000; i++)
{
var text = i;
SimpleText.Dispatcher.BeginInvoke(
// this is now asynchronous so non-blocking
() => SimpleText.Text =
text.ToString(CultureInfo.InvariantCulture));
}
});
}