27

実行している大きな操作で次のメッセージが表示されます。

CLRは、COMコンテキスト0x1fe458からCOMコンテキスト0x1fe5c8に60秒間移行できませんでした。宛先コンテキスト/アパートメントを所有するスレッドは、ほとんどの場合、非ポンピング待機を実行しているか、Windowsメッセージをポンピングせずに非常に長時間実行されている操作を処理しています。この状況は一般にパフォーマンスに悪影響を及ぼし、アプリケーションが応答しなくなったり、メモリ使用量が時間の経過とともに継続的に蓄積したりする可能性さえあります。この問題を回避するには、すべてのシングルスレッドアパートメント(STA)スレッドで、ポンピング待機プリミティブ(CoWaitForMultipleHandlesなど)を使用し、長時間実行される操作中にメッセージを定期的にポンピングする必要があります。

長時間の操作でこのエラーが発生しないように、Windowsメッセージを送信するにはどうすればよいですか?

4

8 に答える 8

21

コンテキストが正確に何であるかは不明です-WinFormsまたはWPFアプリのUIスレッドで長時間実行されるタスクを実行していますか?その場合は、それを行わないでください。を使用するBackgroundWorkerか、スレッドプールまたは新しいスレッドでタスクを直接実行します(UIを使用するControl.Invoke/BeginInvokeDispatcher、更新する必要がある場合)。あなたの大きな操作が不平を言っているCOMコンポーネントを使用する場合、それはより難しくなります...

于 2011-01-26T16:06:44.430 に答える
7

私が知っているように、これは接続されたデバッガーでのみ発生します。本番環境では、この例外が発生することはありません。

于 2011-01-26T16:16:34.387 に答える
4

これがデバッガー内で発生する場合は、ContextSwitchDeadlock MDAが原因である可能性があります。これは、オフにすることができます(Visual Studioの[例外]ウィンドウを使用)。ただし、これはより大きな問題を示しています。UIスレッドで長時間実行する操作を実行しないでください。

于 2011-01-26T16:07:19.373 に答える
3

これらのシナリオでは、Application.DoEventsを使用する傾向があります。それがあなたの状況でうまくいくかどうかはわかりませんが。System.Windows.Formsへの参照が必要ですが、コンソールアプリでも機能します。

または、アプリのマルチスレッドを試すこともできます。

于 2011-01-26T16:07:05.203 に答える
2

従来のwin32メソッドは次のとおりです。

void PumpMessages()
{
    MSG msg;
    for( ;; ) {
        if( !PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) {
            return;
        }
        if( msg.message == WM_QUIT ) {
            s_stopped = true;
            return;
        }
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

しかし、私はあなたが.NETを使用していることを収集します。

于 2011-01-26T16:06:57.963 に答える
1

WinFormsプロジェクトからConsoleAppプロジェクトに切り替えるときにこれに遭遇しました。のMain()メソッドには、WinFormsテンプレートからProgram.cs不要な属性が残っていました。[STAThread]属性を削除すると、エラーがなくなりました。

于 2020-02-10T23:35:03.263 に答える
0

UIがフリーズしないように、長時間実行される操作を別のスレッドで処理する必要があります。これにより、上記の問題も解決されます

于 2011-01-26T16:06:13.543 に答える
0

私はこれが何年も前に尋ねられたことを知っています、しかしこれが将来他の人を助けることを願っています。バックグラウンドワーカーを実行したり、メッセージを送信したりすることを心配したくない場合、簡単な回避策はUIで何かを更新することです。たとえば、私は自分だけが使用するツールを持っているので、UIスレッドを使用するかどうかは気にしません。そのため、UIのtextbox.textを作業中のものに更新するだけです。これがコードの抜粋です。これは非常にハッキーで、おそらく専門的に行うには間違った方法ですが、機能します。

for (int i = 0; i < txtbxURL.LineCount; i++)
{
    mytest.NavigateTo(mytest.strURL);
    mytest.SetupWebDoc(mytest.strURL);
    strOutput = mytest.PullOutPutText(mytest.strURL);
    strOutput = mytest.Tests(strOutput);
    mytest.CheckAlt(mytest.strURL);
    mytest.WriteError(txtbxWriteFile.Text);
    txtblCurrentURL.Text = mytest.strURL;
    //This ^^^ is what is being updated, which keeps the thread from throwing the exception noted above.
}
于 2017-11-13T16:01:48.637 に答える