如何阻止C#WPF中的UI挂起?

时间:2018-06-07 08:36:21

标签: c# asynchronous async-await

我有一个C#脚本连接到远程服务器并显示本地组的所有成员。该脚本正在运行,但在搜索/连接到服务器时会挂起。

我在WPF中有以下必填字段:

  1. ServerList(组合框)
  2. UserAccess(文本框多行)
  3. DataGridResult(输出的DataGrid)
  4. 这是我的异步/等待脚本,但仍然挂起:

    private async void ButtonRun_Click(object sender, EventArgs e)
    {
        if (UserAccess.SelectedItem == null)
        {
            MessageBox.Show("What Access are we going to display?");
            return;
        }
    
        string[] separate = new string[] { "\r\n" };
        string[] strServers = ServerList.Text.Split(separate, StringSplitOptions.RemoveEmptyEntries);
    
        if (strServers == null || ServerList.Text == "")
        {
            MessageBox.Show("There are no Servers Defined!");
            return;
        }
    
        int strServersCount = ServerList.LineCount;
    
        DataTable temptable = new DataTable();
        temptable.Columns.Add("Server");
        temptable.Columns.Add("Comments");
    
        ButtonRun.IsEnabled = false;
    
        await Task.Run(() =>
        {
            this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                {
                    for (var i = 0; i <= strServersCount - 1; i++)
                    {
                        try
                        {
                            DirectoryEntry directoryServers = new DirectoryEntry("WinNT://" + strServers[i] + ",computer");
                            DirectoryEntry directoryGroup = directoryServers.Children.Find(UserAccess.Text + ",group");
                            object members = directoryGroup.Invoke("members", null);
    
                            foreach (object GroupMember in (IEnumerable)members)
                            {
                                DirectoryEntry directoryMember = new DirectoryEntry(GroupMember);
                                Console.WriteLine(directoryMember.Name + " | " + directoryMember.Path);
                                temptable.Rows.Add(strServers[i], directoryMember.Name + " | " + directoryMember.Path);
                            }
    
                        }
                        catch (Exception ex)
                        {
                            temptable.Rows.Add(strServers[i], "Error: " + ex.InnerException + " | " + ex.Message);
                        }
                        DataGridResult.ItemsSource = temptable.DefaultView;
                        ButtonRun.IsEnabled = true;
                    }
                }));
        });
    }
    

1 个答案:

答案 0 :(得分:0)

尝试修复此问题,未经测试:

    string userAccessText = UserAccess.Text;
    await Task.Run(() =>
    {
        //this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
        //        {
                    for (var i = 0; i <= strServersCount - 1; i++)
                    {
                        try
                        {
                            DirectoryEntry directoryServers = new DirectoryEntry("WinNT://" + strServers[i] + ",computer");
                            DirectoryEntry directoryGroup = directoryServers.Children.Find(userAccessText + ",group");
                            object members = directoryGroup.Invoke("members", null);

                            foreach (object GroupMember in (IEnumerable)members)
                            {
                                DirectoryEntry directoryMember = new DirectoryEntry(GroupMember);
                                Console.WriteLine(directoryMember.Name + " | " + directoryMember.Path);
                                temptable.Rows.Add(strServers[i], directoryMember.Name + " | " + directoryMember.Path);
                            }

                        }
                        catch (Exception ex)
                        {
                            temptable.Rows.Add(strServers[i], "Error: " + ex.InnerException + " | " + ex.Message);
                        }
                      //  DataGridResult.ItemsSource = temptable.DefaultView;
                     //   ButtonRun.IsEnabled = true;
                    }
           //     }));  // End of Invoke
    });  

    DataGridResult.ItemsSource = temptable.DefaultView;
    ButtonRun.IsEnabled = true;

基本思想是将所有非GUI内容放入Task中,然后在等待该Task之后使用异步OnClick方法中的数据。