问题是调度程序.调用 http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke(VS.100).aspx阻塞 UI 线程,所以任何Invoke
应尽可能小。
将耗时的代码放在调用之外来解决问题。
正如 @RohitVals 所指出的,您无法从后台线程访问 UI 控件,因此您必须使用 2 个调用 - 一个用于获取文本值,一个用于设置ItemsSource
:
Thread test = new Thread(() =>
{
String text, password, ipText, domainText;
// !!!!!!This one should be simple Invoke because otherwise variables may not get their
// values before calls. Thanks @ScottChamberlain.!!!!!!
datagrid_Disks.Dispatcher.Invoke(
new Action(() =>
{
text = textbox_Username.Text;
password = textbox_password.Password;
ipText = textbox_IP.Text,
domainText = textbox_Domain.Text
}));
var result = Server.GetDisksInfo(text,
password,
ipText,
domainText);
datagrid_Disks.Dispatcher.BeginInvoke(
new Action(() =>
{
datagrid_Disks.ItemsSource = result;
}));
});
test.Start();
或者(感谢@RohitVals)
您可以在运行线程之前获取这些值以避免双重调度:
text = textbox_Username.Text;
// ...
Thread test = ...
OR
您可能想尝试 MVVM 模式 -http://msdn.microsoft.com/en-us/magazine/dd419663.aspx http://msdn.microsoft.com/en-us/magazine/dd419663.aspx。它可能看起来令人生畏,而且太复杂,一开始没有或几乎没有优势,但随着时间的推移,你会看到它的优点。
这篇特别的文章涉及 MVVM 和 Dispatcher -http://msdn.microsoft.com/en-us/magazine/dn630646.aspx http://msdn.microsoft.com/en-us/magazine/dn630646.aspx
P.S.:如果你的GetDisksInfo
方法使用延迟执行(如 LINQ),那么您应该在使用它之前枚举结果:
var result = Server.GetDisksInfo(text,
password,
ipText,
domainText).ToArray();