螺纹冻结主UI [英] Thread freezes main UI

查看:178
本文介绍了螺纹冻结主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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆