Последствия CheckForIllegalCrossThreadCalls = false - PullRequest
5 голосов
/ 07 апреля 2010

Я недавно обновил приложение с VS2003 на VS2008, и я знал, что буду иметь дело с хостом «Межпотоковая операция недопустима: доступ к элементу управления myControl осуществляется из потока, отличного от потока, в котором он был создан»обработка этого, как я полагаю, является правильным способом (см. пример кода ниже).Я сталкиваюсь с многочисленными элементами управления, которые будут нуждаться в подобном исправлении.Не желая иметь подобный код для каждой метки, текстового поля и т. Д., К которым обращается поток не из пользовательского интерфейса.Каковы последствия просто установки CheckForIllegalCrossThreadCalls = false для всего приложения?

Я нашел статью CodeProject с различными обходными путями и предупреждением внизу, чтобы НЕ устанавливать свойство.Я ищу другие мнения / опыт по этому вопросу.

private void ShowStatus(string szStatus)
{
    try
    {
        if (this.statusBar1.InvokeRequired) { BeginInvoke(new MethodInvoker(delegate() { ShowStatus(szStatus); })); }
        else { statusBar1.Panels[0].Text = szStatus; }
    }
  catch (Exception ex)
  {
    LogStatus.WriteErrorLog(ex, "Error", "frmMNI.ShowStatus()");
  }
}

Я нашел другую статью с некоторыми возможными решениями SO Вопрос 2367718

Ответы [ 2 ]

5 голосов
/ 07 апреля 2010

Когда вы не отлаживаете, у вас все еще будут проблемы.

Из документации Control.CheckForIllegalCrossThreadCalls :

Обратите внимание, что незаконное пересечение-потоковые вызовы всегда будут вызывать исключение, когда приложение запускается вне отладчика.

Вам необходимо исправить проблемы.

При этом вы упомянули:

Не желая иметь подобный код для каждой метки, текстового поля и т. Д., К которым обращается поток, не являющийся пользовательским интерфейсом.

Я бы пересмотрел эту позицию.Вы должны попытаться переместить логику, выполняющуюся в отдельном потоке, в отдельные методы или классы, что, в свою очередь, значительно упростит маршалинг вызовов обратно в пользовательский интерфейс.Со временем это сделает ваш код намного более надежным и обслуживаемым.

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

Редактировать:

Например, похоже, что вы загружаете данные.Скажем, у вас (в фоновом потоке) ваш метод загрузки данных:

var myData = LoadData();
this.Invoke( new Action( () =>
    {
        // Just set all of your data in one shot here...
        this.textBox1.Text = myData.FirstName;
        this.textBox2.Text = myData.LastName;
        this.textBox3.Text = myData.NumberOfSales.ToString();
    }));
3 голосов
/ 07 апреля 2010

В разделе примечаний документации для CheckForIllegalCrossThreadCalls довольно ясно сказано, что это не очень хорошая идея

Когда поток, отличный от создания поток управления пытается получить доступ один из методов этого контроля или свойства, это часто приводит к непредсказуемые результаты. Обычный неверная активность потока - это вызов не та нить, которая обращается к свойство Handle элемента управления. Задавать CheckForIllegalCrossThreadCalls to правда найти и диагностировать эту тему активность легче при отладке. Обратите внимание, что незаконные вызовы между потоками всегда будет вызывать исключение, когда приложение запускается за пределами отладчик.

...