c # Thread to Thread Exception, загрузка данных в datagridview при использовании Progressbar во второй форме - PullRequest
0 голосов
/ 10 апреля 2019

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

Я знаю, что загрузка данных в приложение приведет к зависанию моего графического интерфейса, поэтому я решил использовать вторую форму, где я вызываю ее из своей основной задачи.

Я звоню

Task task = new Task(LeftJoinTables);
task.Start();

тогда в LeftJoinTables я запусту этот код

...
foreach(DataRow rows in FileJoinMail.Rows)
            {
                wfrm.UpdateProgressBar(++i);
                dataGridView1.Rows.Add(
                    false, //Checkbox
                    rows["Fullpath"],
                    rows["Filename"],
                    rows["File Size"],
                    rows["UserID"],
                    rows["E-Mail"],
                    rows["Date"]);
                wfrm.ProcInfo($@"Loading Data [{i.ToString()}/{count.ToString()}]");

            }

В моем втором классе формы я получил этот метод, который вызывает Waitform, которая обновляет индикатор выполнения и метку с информацией

public void ProcInfo(string message)
    {
        this.Invoke((MethodInvoker)delegate
        {
            ProcInfoLabel.Text = message;
        });
    }

public void UpdateProgressBar(int value)
    {
        this.Invoke((MethodInvoker)delegate
        {
            ProcBar.Value = value;
        });
    }

Но с этого момента я получил конфликт между потоками .. Я думал, что использование invoke решит это ..

1 Ответ

1 голос
/ 10 апреля 2019

По сути, пользовательский интерфейс Windows (и элементы управления в них) обновляется с помощью насоса сообщений (очереди) и для его работы должен быть создан дескриптор элемента управления. Простой способ убедиться в этом - убедиться, что ваша форма видима (а поскольку это индикатор выполнения, она должна быть видимой).

    private void button1_Click(object sender, EventArgs e)
    {
        wfrm.Show(); // make sure you are making the form visible before updating
        Task task = new Task(LeftJoinTables);
        task.Start();
    }
    private void LeftJoinTables()
    {
        wfrm.ProcInfo("test");
    }

Кроме того, ваш вызов для обновления сетки данных потребует также вызова.

Если вы хотите принудительно создать дескриптор управления, не показывая его, вы можете использовать следующее (взято из https://blogs.msdn.microsoft.com/mapo/2011/04/27/forcing-handle-creation-in-a-net-windows-forms-control/):

if (!mycontrol.IsHandleCreated)
   {
       // This call forces creation of the control's handle.
       IntPtr handle = mycontrol.Handle;
   }

Аналогичная проблема: Form.Invoke () не запускается, когда форма скрыта,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...