Подтвердить что ты не робот

CLR не смог перейти из контекста COM [...] в течение 60 секунд

Я получаю эту ошибку в коде, который работал. Я не изменил код.

Вот полная ошибка:

CLR не смог перейти из контекста COM 0x3322d98 в контекст COM 0x3322f08 в течение 60 секунд. Поток, который владеет целевым контекстом/квартирой, скорее всего, либо выполняет ненакачивание, либо обрабатывает очень длительную операцию без перекачки сообщений Windows. Эта ситуация, как правило, имеет отрицательное влияние на производительность и может даже привести к тому, что приложение становится неактивным или память автоматически накапливается с течением времени. Чтобы избежать этой проблемы, все потоки с одной резьбой (STA) должны использовать примитивы ожидания накачки (например, CoWaitForMultipleHandles) и регулярно накачать сообщения во время длительных операций.

И вот код, который вызвал его:

var openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
openFileDialog1.DefaultExt = "mdb";
openFileDialog1.Filter = "Management Database (manage.mdb)|manage.mdb";

//Stalls indefinitely on the following line, then gives the CLR error
//one minute later.  The dialog never opens.
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
    ....
}

Да, я уверен, что диалог не открыт в фоновом режиме, и нет, у меня нет явного кода COM или неуправляемого сортировки или многопоточности.

Я не знаю, почему OpenFileDialog не откроется - любые идеи?

4b9b3361

Ответ 1

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

Мое обходное решение выглядит так:

string initialDirectory = ...; //Figure out an initial directory from somewhere
openFileDialog1.InitialDirectory = !Directory.Exists(initialDirectory)
                                       ? Path.GetPathRoot(Environment.SystemDirectory)
                                       : initialDirectory;

Ответ 2

Таким образом, он жалуется на контекст COM, даже если вы явно не используете COM, потому что открываете собственный диалог оболочки под всем этим прекрасным кодом С#, а оболочка использует COM.

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

Что нужно попробовать:

  • Сначала я попробую, как AaronLS предложить, максимально упростив openFileDialog. Не пытайтесь ничего настраивать; просто создайте нового парня и позвоните ShowDialog(). Если это решает проблему, вы только что дали ей неверные параметры, и мы можем поговорить о последствиях этого. Однако, если это не сработает, это означает, что что-то идет не так на поверхности земли.

  • Одна из возможных причин этого может произойти, потому что у вас установлено расширение оболочки, которое делает что-то плохое. Самое лучшее, что вам нужно сделать, это break-in (ctrl+break in Visual Studio, я думаю, или debug->break all в строке меню) и получить полный стек для нас. Мы должны уметь выявить виновника, увидев, кто находится в стеке, когда появится диалоговое окно.

Ответ 3

Одно исправление проблемы - перейти в меню "Отладка → Исключения → Управляемые отладки в Visual Studio" и снять флажок ContextSwitchDeadlock

От http://blog.wpfwonderland.com/2007/08/16/clr-has-been-unable-to-transition-from-com-context-for-60-seconds/

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

Ответ 4

У меня возникла эта проблема при работе с большой базой данных, и она заставила замораживание пользовательского интерфейса в течение длительного периода времени. Поэтому я помещаю коды в BackgroundWorker, и теперь проблема исчезла. благодаря @i_am_jorf

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

private void btnConvert_Click(object sender, EventArgs e)
{
  Cursor = Cursors.WaitCursor;
  bgwConvert.RunWorkerAsync();
}

private void bgwConvert_DoWork(object sender, DoWorkEventArgs e)
{
  //My taking-lots-of-time codes
}

private void bgwConvert_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  Cursor = Cursors.Default;
  MessageBox.Show("Done");
}

Ответ 5

У меня также была эта проблема, и я решил ее, изменив мою инфраструктуру .Net до последней версии (.NET Framework 4.5 в моем случае, из свойств проекта Window- > Debug- > .Net Framework) и изменения процессора type from x86 to Any CPU (в свойствах проекта Window- > Build- > Platform Target).