WPF GUI冻结

时间:2018-03-20 14:03:39

标签: c# wpf

遇到WPF问题。我应该提一下,我对WPF非常新。我正在为自己构建小型应用程序以了解主题。

目前我无法更新列表框,调用我的“_classes”文件夹中的一个类,该文件夹从远程计算机获取信息。我把它放在一个不同的文件夹中的原因是为了避免XAML背后的所有混乱。如果我想把我的代码放在XAML后面,我可以解决GUI冻结问题,这与我读过的不太理想。

在这里或其他网站上给出或搜索的示例有点令人困惑,没有任何解释。如果有人能够将评论放在我被困的地方,并且在他们纠正之后指出我做错了,那将是非常棒的。毕竟我正在努力学习这一点。展望未来,最好的方法是实现这些长期处理任务吗?创建一个文件夹?打电话课?不同方案?不同的项目?我一直在阅读很多关于此的内容,每个人似乎对此有自己的看法。

另外,我搜索了这个并且没有在哪里。我觉得我会成为第一个问这个但是响应式UI需要MVVM的人吗?我可以实现async / await并完成它,就像我在下面的示例中尝试做的那样吗?

这是我目前的代码。虽然我得到了我想要的结果,但GUI没有响应。我在那里添加了thread.sleep来模拟一个很长的过程。

虽然我尝试了不同的东西,但这是我目前的最新代码。

这就是我想到的应用程序会做的事情:

  • 点击按钮。列表框显示“获取信息”
  • 该过程在后台运行(收集信息)
  • GUI是响应式的,我可以在GUI上做其他事情(最小化,更改标签等)。
  • 完成此过程后,将信息添加到列表框中。

提前谢谢大家。

PS。请暂时忽略命名约定。我已经研究了一段时间,只是放弃了这一部分,直到我真正解决了这个问题。

XAML

<StackPanel>

    <Button Name="test" Height="30" Width="70"  Background="red" Content="Submit"
                    Click="test_Click" />

    <ListBox x:Name="listboxResult"  />
</StackPanel>

XAML背后的代码

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
    }

    private async void test_Click(object sender, RoutedEventArgs e)
    {
        listboxResult.Items.Clear();
        listboxResult.Items.Add("Getting listbox results...");
        try
        {
            await Task.Factory.StartNew(() =>
            {
                getResults("Passing String Argument", listboxResult);
            });

        }
        catch (Exception)
        {

            throw;
        }

    }

    private void getResults(string v, ListBox listBoxIn)
    {
        this.Dispatcher.Invoke((Action)(() =>
        {
            ReturnListbox _result = new ReturnListbox(v, listBoxIn);
        }));

    }
}

我在_classes文件夹中的课程

public class ReturnListbox
{
    private ListBox _myListBox;
    private string _ComputerName;
    public ListBox MyListBox
    {
        get { return _myListBox; }
        set { _myListBox = MyListBox; }
    }
    public string CName
    {
        get { return _ComputerNAme; }
        set { _ComputerName = CName; }
    }

    public ReturnListbox(string ComputerName, ListBox IncomingListBox)
    {

        BuildListBox(ComputerName, IncomingListBox);

    }

    private void BuildListBox(string CName, ListBox MyListBox)
    {
        Thread.Sleep(5000);
        _myListBox = MyListBox;
        MyListBox.Items.Clear();


        try
        {
          ManagementScope Manage = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", CName));
                    Manage.Connect();
                    ObjectGetOptions objectOptions = new ObjectGetOptions();
                    ManagementPath managementPath = new ManagementPath("Win32_OperatingSystem");
                    ManagementClass Class = new ManagementClass(Manage, managementPath, objectOptions);

                    foreach (ManagementObject Object in Class.GetInstances())
                    {
                        // Display the remote computer information
                        MyListBox.Items.Add(string.Format("Computer Name : {0}", Object["csname"]));
                        MyListBox.Items.Add(string.Format("Windows Directory : {0}", Object["WindowsDirectory"]));
                        MyListBox.Items.Add(string.Format("Operating System: {0}", Object["Caption"]));
                        MyListBox.Items.Add(string.Format("Version: {0}", Object["Version"]));
                        MyListBox.Items.Add(string.Format("Manufacturer : {0}", Object["Manufacturer"]));

                    }
      {
      catch (Exception ex)
        {
            MyListBox.Items.Add(string.Format("Something is going on..."));

        }
    }

1 个答案:

答案 0 :(得分:1)

您可以在WPF here

中阅读有关异步编程的信息
  

如果有人能够将评论放在我遇到的地方

,那将是非常棒的

您正在使用的不是MVVM。您还需要了解有关threading

的更多信息
  

是响应式UI所必需的MVVM吗?我可以实现async / await和   完成它就像我在下面的例子中尝试做的那样?

MVVM不是必需的。您可以使用async / await。它们彼此无关

  

虽然我得到了我想要的结果,但GUI没有响应

您的GUI没有响应,因为您正在UI线程中执行任务。通过调用this.Dispatcher.Invoke,你说你希望代码内部在Dispatcher线程中执行(实际上负责处理UI)