Есть ли какое-либо решение для исключения незаконной перекрестной резьбы? - PullRequest
16 голосов
/ 05 августа 2008

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

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

Ответы [ 4 ]

3 голосов
/ 05 августа 2008

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

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 и как бы ужесточает код.

1 голос
/ 05 августа 2008

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

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

public void DoDataBind()
{
    DataBind();
}

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

0 голосов
/ 08 августа 2008

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

0 голосов
/ 05 августа 2008

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

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

this.BindData.Invoke();

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

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