C# wpfgui冻结
WPF出现了问题。我应该提到的是,我是WPF的新手。我正在为自己构建一些小应用程序来理解这些主题 目前,我正在更新一个列表框,该列表框调用了我的“\u classes”文件夹中的一个类,该文件夹从远程计算机获取信息。我之所以把它放在另一个文件夹中,是为了避免XAML背后的混乱。如果我想把我的代码放在XAML后面,我可以解决GUI冻结的问题,这在我所阅读的内容中并不理想 在这里或其他网站上给出或搜索的例子有点混乱,没有任何解释。如果有人真的能把评论放在我被卡住的地方,并在他们纠正后指出我做错了什么,那就太棒了。毕竟我正在努力学习这一点。展望未来,实现此类长处理任务的最佳方式是什么?创建文件夹?叫课?不同的解决方案?不同的项目?等等,我读了很多关于这方面的书,每个人似乎都有自己的看法 还有,我搜索了一下,没有找到。我觉得我将是第一个问这个问题的人,但是MVVM对于响应式UI是必要的吗?我可以实现async/await并像下面的示例中那样使用它吗 这是我目前掌握的密码。虽然我得到了想要的结果,但GUI没有响应。我在那里添加了thread.sleep来模拟一个长过程 虽然我尝试了不同的方法,但这是我目前拥有的最新代码 这就是我认为该应用程序可以做到的:C# wpfgui冻结,c#,wpf,C#,Wpf,WPF出现了问题。我应该提到的是,我是WPF的新手。我正在为自己构建一些小应用程序来理解这些主题 目前,我正在更新一个列表框,该列表框调用了我的“\u classes”文件夹中的一个类,该文件夹从远程计算机获取信息。我之所以把它放在另一个文件夹中,是为了避免XAML背后的混乱。如果我想把我的代码放在XAML后面,我可以解决GUI冻结的问题,这在我所阅读的内容中并不理想 在这里或其他网站上给出或搜索的例子有点混乱,没有任何解释。如果有人真的能把评论放在我被卡住的地方,并在他们纠正后指出我做错了什么
- 点击一个按钮。列表框显示“获取信息”
- 进程正在后台运行(收集信息)
- GUI响应迅速,我可以在GUI上做其他事情(最小化、更改选项卡等)
- 流程完成后,将信息添加到列表框中李>
<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
尽可能晚,只有在需要时才调用