2010-04-30 12 views
30

Otrzymuję ten błąd na kodzie, który działał. Nie zmieniłem kodu.CLR nie może przejść z kontekstu COM [...] przez 60 sekund.

Oto pełna błąd:

The CLR has been unable to transition from COM context 0x3322d98 to COM context 0x3322f08 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

A oto kod, który go spowodował:

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) 
{ 
    .... 
} 

Tak, jestem pewien, że okno nie jest otwarte w tle, a nie, Nie mam żadnego wyraźnego kodu COM ani niezarządzanego zestawiania lub wielowątkowości.

Nie mam pojęcia, dlaczego OpenFileDialog się nie otworzy - jakieś pomysły?

+0

Nigdy nie widziałem .Filter wykorzystywane bez gwiazdką. Spróbuj '" Zarządzanie bazą danych (* .mdb) | * .mdb "' Nie wiem, czy to może być mylące coś w ramach. – AaronLS

+1

@Aaron: Jak już powiedziałem, zadziałało to wczoraj. Szukam tylko określonego pliku o tej konkretnej nazwie. –

+2

To nie jest błąd, to ostrzeżenie * debuggera *. Wyprodukowany przez asystenta debugowania zarządzanego przez ContextSwitchDeadlock i zaprojektowany do ostrzeżenia o możliwym impasie z powodu marszczenia COM. OpenFileDialog używa dużo COM. Otrzymasz go tylko podczas debugowania aplikacji. Limity czasu sieci są bardzo długie, trzeba będzie chwilę poczekać, zanim zostanie zgłoszony prawdziwy wyjątek. –

Odpowiedz

11

Wyliczyłem - automatycznie przenosi Cię do ostatniej lokalizacji, w której się pojawiłeś za każdym razem, gdy otwiera się okno dialogowe. Jeśli ta lokalizacja jest lokalizacją sieciową, która już nie istnieje (np. Drugi komputer jest wyłączony), po prostu zostanie zawieszony na zawsze.

Moja obejście wygląda następująco:

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

To narzeka na kontekst COM, nawet jeśli nie używasz jawnie COM, ponieważ otwierasz natywne okno dialogowe pod tym cudownym kodem C#, a powłoka używa COM.

Ta wiadomość mówi, że cokolwiek próbuje zrobić, robi to w wątku UI, a nie w przyjemny sposób, a to zajmuje dużo czasu. Oczywiście, cokolwiek jest nie tak, nie jest twoją winą per se, więc możesz zignorować większość porad, które ci daje.

warte spróbować:

  1. Najpierw chciałbym spróbować, jak AaronLS sugerują, upraszczając openFileDialog jak najwięcej. Spróbuj nie ustawiać niczego; po prostu stwórz nowego faceta i zadzwoń pod numer ShowDialog(). Jeśli to rozwiąże problem, to właśnie podałeś mu zniekształcone parametry i możemy porozmawiać o implikacjach tego. Jeśli jednak to nie zadziała, oznacza to, że coś jest nie tak z ziemią muszli.

  2. Jednym z możliwych powodów takiego stanu rzeczy jest to, że masz zainstalowane rozszerzenie powłoki, które robi coś złego. Najlepszą rzeczą do zrobienia jest break-in (ctrl+break in Visual Studio myślę, lub debug->break all na pasku menu) i uzyskać kompletny stos dla nas. Powinniśmy być w stanie zidentyfikować sprawcę, widząc, kto jest na stosie, gdy pojawi się okno dialogowe.

4

Jedna poprawka dla tego problemu jest, aby przejść do Debug -> Wyjątki -> menu Zarządzane Debug Asystenci w Visual Studio i odznacz ContextSwitchDeadlock

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

Aktualizacja: Proszę, nie lekceważ, jeśli sądzisz, że to obejście jest okropnym pomysłem. Wiele osób wypróbowało wiele rozwiązań wymienionych tutaj jako odpowiedzi, ale moje jedyne rozwiązanie pomogło im. Dlatego odpowiedź wciąż ma pozytywny wynik.

+0

To nie działa: próbowałem. –

+24

ukrywanie wyjątku nie oznacza, że ​​zniknęło! – Haris

+2

To jest ** okropny ** pomysł. – Dan

2

Też miałem ten problem i rozwiązałem go, zmieniając moją platformę .Net na najnowszą (.Net framework 4.5 w moim przypadku; od właściwości projektu Okno-> Debug-> .Net Framework) i zmieniając typ procesora z x86 do Any CPU (we właściwościach projektu Okno-> Build-> Platforma docelowa).

+0

Próbowałem tego i ma to sens, jeśli jesteś na maszynie 64-bitowej, ale niestety to nic dla mnie nie rozwiązało. VS 2013 Premium/Windows 10 i koduję dodatek VSTO dla programu Excel 2016. –

4

Ten problem wystąpił podczas pracy z dużą bazą danych i spowodował zablokowanie interfejsu użytkownika przez dłuższy czas. Więc umieszczam kody w BackgroundWorker, a teraz problem zniknął. Dzięki @i_am_jorf

What this message is telling you is that whatever it's trying to do, it's doing it on the UI thread and not in a nice way, and that seems to be taking a long time.

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"); 
} 
Powiązane problemy