Как обновить управление потокобезопасным способом - PullRequest
3 голосов
/ 30 мая 2011

У меня есть класс windows.form.userControl, и во время выполнения я хочу динамически добавить некоторые ссылки. Когда я применяю этот фрагмент кода внутри метода Load, он отлично работает.

for (int i = 0; i < 10; i++)
     {
       linkLabel = new System.Windows.Forms.LinkLabel();
       linkLabel.Name = i.ToString();
       linkLabel.Text = i.ToString();
       linkLabel.LinkClicked += new  System.Windows.Forms.LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked);
       this.Controls.Add(linkLabel);
       linkLabel.Top = top;
       top += 30;
      }

Но когда я переместу этот фрагмент кода внутрь backgroudworker doWork метод, он выдаст недопустимое исключение операции, связанное с проблемой перекрестного потока в этой строке: - this.Controls.Add (linkLabel);

Как мне сделать это как потокобезопасную операцию? Я новичок в C #, и я использую C # 4.0, используя VS 2010. Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 30 мая 2011

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

Используйте этот код, чтобы исправить это

if(this.InvokeRequired)
   this.Invoke(new Action(() => {this.Controls.Add(linkLabel);}));
else
   this.Controls.Add(linkLabel); 
3 голосов
/ 30 мая 2011

Вы должны синхронизировать метод с потоком пользовательского интерфейса. Вы можете использовать свойство Control.InvokeRequired для проверки необходимости синхронизации и Control.Invoke для синхронного вызова любого делегата.

private void AddLinkLabels()
{
    // If synchronization is needed, i.e. when this method is called on a non-UI thread, invoke the method synchronized and return immediately.
    if(InvokeRequired)
    {
        Invoke(new MethodInvoker(AddLinkLabels));
        return;
    }

    for (int i = 0; i < 10; i++)
    {
        linkLabel = new System.Windows.Forms.LinkLabel();
        linkLabel.Name = i.ToString();
        linkLabel.Text = i.ToString();
        linkLabel.LinkClicked += new  System.Windows.Forms.LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked);
        this.Controls.Add(linkLabel);
        linkLabel.Top = top;
        top += 30;
    }
}
1 голос
/ 30 мая 2011

Ответ от Stecya также можно поместить в метод расширения, подобный этому .

0 голосов
/ 30 мая 2011

Как уже сказал Stecya: Вы должны переключиться на поток, который создал этот элемент управления, чтобы взаимодействовать с ним. Это может быть сделано в событии ProgressChanged backgroundworkers, потому что оно работает в потоке пользовательского интерфейса, без необходимости вызывать. Образец в MSDN .

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