Любое решение для исключения Illegal Cross Thread Operation?
При привязке данных в C# поток, изменяющий данные, также вызывает изменение элемента управления. Но если этот поток не тот, в котором был создан элемент управления, вы получите исключение Illegal Cross Thread Operation.
Есть ли способ предотвратить это?
Ответов (4)4
Поскольку у меня нет тестового примера, я не могу гарантировать это решение, но мне кажется, что здесь подойдет сценарий, аналогичный тому, который используется для обновления индикаторов выполнения в разных потоках (используйте делегат).
public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);
public void DoDataBind()
{
DataBind();
}
Если привязка данных должна выполняться определенным потоком, позвольте этому потоку выполнять работу!
Если вызов потока является «незаконным» (то есть вызов DataBind влияет на элементы управления, которые не были созданы в потоке, из которого он вызывается), вам необходимо создать делегат, чтобы даже если решение / подготовка для DataBind не выполнялись в поток, создающий элемент управления, любая их результирующая модификация (например, DataBind ()) будет.
Вы бы вызывали мой код из рабочего потока следующим образом:
this.BindData.Invoke();
Это приведет к тому, что исходный поток выполнит привязку, которая (при условии, что это поток, создавший элементы управления) должен работать.
Вы должны уметь делать что-то вроде:
if (control.InvokeRequired)
{
control.Invoke(delegateWithMyCode);
}
else
{
delegateWithMyCode();
}
InvokeRequired - это свойство в элементах управления, чтобы увидеть, находитесь ли вы в правильном потоке, тогда Invoke вызовет делегат в правильном потоке.
ОБНОВЛЕНИЕ: Собственно, на моей последней работе мы сделали что-то вроде этого:
private void SomeEventHandler(Object someParam)
{
if (this.InvokeRequired)
{
this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
}
// Regular handling code
}
что устраняет необходимость в блоке else и как бы ужесточает код.