Любое решение Нелегальная исключение Cross Thread операции?

голоса
15

Когда данные связываются в C #, поток, который изменяет данные СЧПУ изменения слишком. Но если этот поток не тот, на котором был создан элемент управления, вы получите недопустимую Cross Thread исключение операции.

Есть в любом случае, чтобы предотвратить это?

Задан 05/08/2008 в 08:45
источник пользователем
На других языках...                            


5 ответов

голоса
3

Если модификация данных не слишком потребляя (то есть, если главная цель фонового потока не фактическое изменение данных) время, попытайтесь переместить раздел, который модифицирует данные делегата и Invoke'ing этот делегат.

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

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

Ответил 05/08/2008 d 09:05
источник пользователем

голоса
3

Вы должны быть в состоянии сделать что-то вроде:

if (control.InvokeRequired)
{
    control.Invoke(delegateWithMyCode);
}
else
{
    delegateWithMyCode();
}

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

UPDATE: На самом деле, на моей последней работе мы сделали что-то вроде этого:

private void SomeEventHandler(Object someParam)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
    }

    // Regular handling code
}

который устраняет необходимость в блок еще и своего рода подкручивает код.

Ответил 05/08/2008 d 08:51
источник пользователем

голоса
1

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

public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);

public void DoDataBind()
{
    DataBind();
}

Если привязки данных необходимо сделать по определенной теме, то пусть что нить сделать работу!

Ответил 05/08/2008 d 08:56
источник пользователем

голоса
0

В WPF и Silverlight привязки инфраструктура заботится о переключении в поток пользовательского интерфейса.

Ответил 08/08/2008 d 17:19
источник пользователем

голоса
0

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

Вы назвали бы мой код из рабочего потока, как так:

this.BindData.Invoke();

Это позволило бы привести исходный поток сделать переплет, который (предполагая, что это поток, который создал элементы управления) должен работать.

Ответил 05/08/2008 d 09:06
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more