Как вы можете предотвратить зависание пользовательского интерфейса в C # WPF? - PullRequest
0 голосов
/ 07 июня 2018

У меня есть сценарий C #, который подключается к удаленному серверу и отображает всех членов локальной группы.Сценарий выполняется, но он зависает при поиске / подключении к серверу.

У меня есть следующие обязательные поля в WPF:

  1. ServerList (выпадающий список)
  2. UserAccess (многострочное текстовое поле)
  3. DataGridResult (DataGrid для вывода)

Вот мой асинхронный / ожидающий сценарий, но все еще зависает:

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 голосов
/ 07 июня 2018

Попытка исправить это, не проверено:

    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;

Основная идея состоит в том, чтобы поместить все элементы, не относящиеся к графическому интерфейсу, внутри Задачи, а затем использовать данные в асинхронном методе OnClick после ожидания этой Задачи..

...