Любое решение для исключения незаконной операции перекрестной резьбы?

Когда вы связываете данные в C #, поток, который изменяет данные, также вызывает изменение элемента управления. Но если этот поток не тот, на котором был создан элемент управления, вы получите исключение Illegal Cross Thread Operation.

Есть ли способ предотвратить это?

5.08.2008 07:45:38
4 ОТВЕТА

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

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

InvokeRequired - это свойство в Controls, позволяющее определить, находитесь ли вы в правильном потоке, тогда Invoke вызовет делегата в правильном потоке.

ОБНОВЛЕНИЕ: На самом деле, на моей последней работе мы сделали что-то вроде этого:

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

    // Regular handling code
}

что устраняет необходимость в блоке else и как бы ужесточает код.

4
5.08.2008 07:58:06

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

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

public void DoDataBind()
{
    DataBind();
}

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

1
5.08.2008 07:56:53

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

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

this.BindData.Invoke();

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

0
5.08.2008 08:06:42

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

0
8.08.2008 16:19:17