Многопоточность, контроль доступа к интерфейсу - PullRequest
3 голосов
/ 07 января 2012

У меня есть простое приложение с обычным потоком пользовательского интерфейса и фоновым работником, в фоновом работнике мне нужно динамически создать LinkLabels и поместить их в FlowLayoutPanel.Чтобы сделать это, мне нужно установить родительский элемент LinkLabel в FlowLayoutPanel.

Вот фрагмент кода, который у меня есть в настоящее время, однако я получаю печально известную «Операция перекрестного потока недопустима» настрока 'l.Parent = panel;'

Я довольно новичок в многопоточных операциях, но я думал, что правильно вызвал, но, очевидно, нет.Есть предложения?

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    FlowLayoutPanel panel = null;
    rssFeedPanel.Invoke(new MethodInvoker(delegate { panel = rssFeedPanel; }));
    l.Parent = panel;
}
else
    l.Parent = rssFeedPanel;

Ответы [ 2 ]

3 голосов
/ 07 января 2012

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

if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate 
    { 
        AddLabel();
    }));
}
else AddLabel();

И поместить вашу логику в метод AddLabel:

private void AddLabel()
{
    LinkLabel l = new LinkLabel();
    l.Parent = rssFeedPanel;
}
3 голосов
/ 07 января 2012

На самом деле вам нужно установить свойство Parent в другом потоке.

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate {
        l.Parent = rssFeedPanel;
    }));
}
else
    l.Parent = rssFeedPanel;

В общем, почти любая операция, связанная с доступом к членам элемента управления пользовательского интерфейса, может быть выполнена только из потока пользовательского интерфейса.Некоторые очевидные исключения: Invoke, InvokeRequired, BeginInvoke и некоторые методы класса BackgroundWorker.

Если вы хотите для этого случая, вы также можете использовать BeginInvoke вместоInvoke.

...