螺纹冻结主UI [英] Thread freezes main UI
问题描述
您好
林目前正在写一个服务器监控应用。
类
Hello
Im currently writing a Server monitoring application.
Classes
public class Server
{
public string SERVERNAME;
public string ENVIRONMENT;
public string VERSION;
public string CPU_PERCETAGE;
public string CPU_NAME;
public string CPU_DESCRIPTION;
public string CPU_VOLTAGE;
}
我现在有一个页面wihtin我的主窗口,我Exucute和填充数据:
方法
I currently have a Page wihtin my mainwindow where I Exucute and fill the data:
Method
try
{
{
Thread test = new Thread(() =>
{
datagrid_Disks.Dispatcher.BeginInvoke(
new Action(() =>
{
datagrid_Disks.ItemsSource = Server.GetDisksInfo(textbox_Username.Text,
textbox_password.Password,
textbox_IP.Text,
textbox_Domain.Text);
}));
});
test.Start();
}
catch (UnauthorizedAccessException)
{
Worker.ShowModernBox("Onjuiste gebruiksersnaam" + Environment.NewLine + "of wachtwoord.");
}
catch (ManagementException)
{
Worker.ShowModernBox("Server geeft geen Response." + Environment.NewLine + "Controleer Aub de instelling.");
}
问题
我mainThread等待线程完成,似乎无法弄清楚为什么会这样。
My mainThread waits for the Thread to finish, cannot seem to figure why this happens.
所有帮助AP preciated!
All help appreciated!
推荐答案
的问题是,<一个href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke(VS.100).aspx"相对=nofollow> Dispatcher.Invoke 阻塞UI线程,因此任何调用
应尽可能的小。
The problem is that the Dispatcher.Invoke blocks the UI thread, so any Invoke
should be as small as possible.
把你的耗时code中的调用之外来解决这个问题。
Put your time-consuming code outside the invoke to solve the issue.
和,因为它已经指出通过@RohitVals您无法访问从后台线程的UI控件,所以你将不得不使用2调用 - 一个拿到文本值,一个集的ItemsSource
:
And as it has been pointed by @RohitVals you can't access the UI control from background thread, so you will have to use 2 invokes - one to get text values, one to set 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)
您可以运行的线程,以避免双重派遣之前获取这些值:
You can get these values before running the thread to avoid the double dispatch:
text = textbox_Username.Text;
// ...
Thread test = ...
或
您可能想尝试MVVM模式 - http://msdn.microsoft .COM / EN-US /杂志/ dd419663.aspx 。它可能看起来令人生畏并没有或几乎没有优势,一开始太复杂,但你会看到随着时间的推移它的优点。
You may want to try the MVVM pattern - http://msdn.microsoft.com/en-us/magazine/dd419663.aspx. It may look intimidating and far too complex for no or little advantages at the beginning, but you will see its merits with time.
这条特别处理MVVM和Dispathcer - http://msdn.microsoft .COM / EN-US /杂志/ dn630646.aspx
This particular article deals with MVVM and Dispathcer - http://msdn.microsoft.com/en-us/magazine/dn630646.aspx
PS:如果你的 GetDisksInfo
方法使用延迟执行(如LINQ),那么你应该使用它之前列举的结果:
P.S.: If your GetDisksInfo
method uses deferred execution (like LINQ) then you should enumerate the result before using it:
var result = Server.GetDisksInfo(text,
password,
ipText,
domainText).ToArray();
这篇关于螺纹冻结主UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!