C# wpfgui冻结

C# wpfgui冻结,c#,wpf,C#,Wpf,WPF出现了问题。我应该提到的是,我是WPF的新手。我正在为自己构建一些小应用程序来理解这些主题 目前,我正在更新一个列表框,该列表框调用了我的“\u classes”文件夹中的一个类,该文件夹从远程计算机获取信息。我之所以把它放在另一个文件夹中,是为了避免XAML背后的混乱。如果我想把我的代码放在XAML后面,我可以解决GUI冻结的问题,这在我所阅读的内容中并不理想 在这里或其他网站上给出或搜索的例子有点混乱,没有任何解释。如果有人真的能把评论放在我被卡住的地方,并在他们纠正后指出我做错了什么

WPF出现了问题。我应该提到的是,我是WPF的新手。我正在为自己构建一些小应用程序来理解这些主题

目前,我正在更新一个列表框,该列表框调用了我的“\u classes”文件夹中的一个类,该文件夹从远程计算机获取信息。我之所以把它放在另一个文件夹中,是为了避免XAML背后的混乱。如果我想把我的代码放在XAML后面,我可以解决GUI冻结的问题,这在我所阅读的内容中并不理想

在这里或其他网站上给出或搜索的例子有点混乱,没有任何解释。如果有人真的能把评论放在我被卡住的地方,并在他们纠正后指出我做错了什么,那就太棒了。毕竟我正在努力学习这一点。展望未来,实现此类长处理任务的最佳方式是什么?创建文件夹?叫课?不同的解决方案?不同的项目?等等,我读了很多关于这方面的书,每个人似乎都有自己的看法

还有,我搜索了一下,没有找到。我觉得我将是第一个问这个问题的人,但是MVVM对于响应式UI是必要的吗?我可以实现async/await并像下面的示例中那样使用它吗

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

虽然我尝试了不同的方法,但这是我目前拥有的最新代码

这就是我认为该应用程序可以做到的:

  • 点击一个按钮。列表框显示“获取信息”
  • 进程正在后台运行(收集信息)
  • GUI响应迅速,我可以在GUI上做其他事情(最小化、更改选项卡等)
  • 流程完成后,将信息添加到列表框中
提前谢谢大家

请暂时忽略命名约定。我已经在这方面工作了一段时间,只是在我真正解决问题之前放弃了这一部分

XAML

<StackPanel>

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

    <ListBox x:Name="listboxResult"  />
</StackPanel>
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);
        }));

    }
}
我的班级在班级文件夹中

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..."));

        }
    }

您可以阅读WPF中的异步编程

如果有人真的能把评论放在我被卡住的地方,那就太棒了

您正在使用的不是您所认为的MVVM。你还需要获得更多的知识

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

MVVM不是必需的。您可以使用async/await。他们彼此没有关系

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


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

您正在创建一个后台线程,其唯一工作是在UI线程上运行的
Dispatcher.Invoke
。因此,您创建的线程实际上是无用的。为什么
线程。睡眠(5000)
?@RonBeyer我添加了它来模拟我将获得的延迟。@Camiloterevento如果我不添加它,那么我会得到“调用线程无法访问此对象,因为它是另一个线程拥有的。”异常。@Besiktas当然可以,我说的是线程是无用的,而不是
调度程序.Invoke
。问题是,您应该调用
Dispatcher.Invoke
尽可能晚,只有在需要时才调用