8

デバッガーが未処理の例外で停止する VS2010 に問題があります。ただし、例外は確実に処理されます。実際、catch ブロックにコードを入れると、F5 キーを押したときにヒットします。Debug -> Exceptions では、「Thrown」チェックボックスがチェックされていないことは間違いないため、IMO には未処理の例外ダイアログがポップアップする理由はまったくありません...

正確なコードを投稿することはできませんが、すぐにサンプルに取り組みます。問題のあるコード セクションの背後にある基本的な考え方は、ハードウェアと通信するスレッドがあり、それとの通信でエラーが発生した場合は、HardwareException. スレッドは で起動されBeginInvoke、 を呼び出すとコールバック ハンドラで例外がキャッチされますEndInvoke

デバッガーで例外がスローされると、「ユーザー コードによって処理されないハードウェア例外」というメッセージ ボックスが表示されます。

編集 - まあ、これは私を夢中にさせています。私のアプリケーションにあるコードを代表するサンプル コードがあり、次のようになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace ConsoleApplication1
{
    public class HardwareException : ApplicationException
    {
        public HardwareException( string message) : base(message) {}
    }

    class Program
    {
        delegate void HardwareTestDelegate();

        static void Main(string[] args)
        {
            HardwareTestDelegate d = new HardwareTestDelegate( HardwareTestThread);
            d.BeginInvoke( HardwareTestComplete, null);
            while( true);
        }

        static void HardwareTestThread()
        {
            throw new HardwareException( "this is a test");
        }

        static void HardwareTestComplete( IAsyncResult iar)
        {
            try {
                AsyncResult ar = (AsyncResult)iar;
                HardwareTestDelegate caller = (HardwareTestDelegate)ar.AsyncDelegate;
                caller.EndInvoke( iar);
            } catch( Exception ex) {
                Console.WriteLine( "Should see this line without getting an unhandled exception message in the IDE");
            }
        }
    }
}

スレッドから HardwareException をスローし、EndInvoke が呼び出されたときに例外を処理します。このサンプル コードを実行すると、予期したとおりに動作するため、Murphy は正しかったと思います。つまり、未処理の例外エラー メッセージが IDE に表示されません。

4

2 に答える 2

2

Microsoft からの応答は、ケース 111053102422121 です 。Allen Wengは次のように書いています。

分析:

参考までに、EndInvoke() を呼び出すと、CLR はコールバック内で例外を再スローします。以下は、EndInvoke() の簡易バージョンです。

public object EndInvoke(IAsyncResult asyncResult)
{
    using (new MultithreadSafeCallScope())
    {
        ThreadMethodEntry entry = asyncResult as ThreadMethodEntry;
         ............
        if (entry.exception != null)
        {
            throw entry.exception;
        }
     }
}

例外ハンドラが提供されている場合、例外はコールバック関数または非同期メソッドで処理されます。これは、デバッガーが接続されていない場合の動作です。

VS.NET で実行すると、デバッガーは非同期メソッド内の例外ハンドラーの存在のみをチェックしているようです。そのようなハンドラーが存在しない場合、デバッガーは例外が処理されていないと判断し、これを通知するエラー メッセージを表示します。

提案:

スタンドアロンで実行すると、アプリケーションは期待どおりに動作するはずです。デバッグ中にエラー メッセージが煩わしい場合は、[例外] ダイアログ ボックス ([デバッグ] > [例外] または CTRL + ATL + E を押す) で [共通言語ランタイムの例外] の [ユーザーが処理されていません] のチェックを外すことで無効にできます。または、非同期メソッドに try/catch を追加できます。後者の場合、例外は null に設定され、EndInvoke() で再スローされません。

于 2011-05-31T11:11:06.907 に答える
0

私はこれと同じ問題を抱えているので、後世のためにこの可能な回避策を投稿します。

.NET コード (上記の例では HardwareTestThread()) に例外をスローするコードで、スローされている例外をキャッチし、「ユーザー未処理」オプションを無効にできる難解な .NET 例外タイプにラップします。 [デバッグ] > [例外] ダイアログで。私の場合、IOException が一部の .NET コードを介して自分のコードに伝播できるようにする必要があったため、IOException をキャッチし、AppDomainUnloadedException にラップしてから、.NET コードを介して catch ブロックに伝播させました。user-unhandled はデフォルトでチェックされておらず、System.dll アセンブリに含まれているため、AppDomainUnloadedException を選択しました。「user-unhandled」オプションを無効にしている限り、どの例外も機能するはずですが、既にプロジェクトにインポートされていました。それのために、あなたはしません

伝播する必要があった IOException をラップするコードは次のとおりです。

public override int Read(byte[] buffer, int offset, int count)
{
    try { return innerStream.Read(buffer, offset, count); }
    catch (IOException ex) { throw new AppDomainUnloadedException("Exception from innerStream: " + ex.Message, ex); }
}

そして、これが伝播に必要な .NET コードの反対側でキャッチしている私のコードです。

try { bytesRead = sslStream.Read(buffer, offset, count); }
catch (Exception ex) { /* ex handled here. */ }
于 2013-01-16T23:04:32.790 に答える