36

私が読んだどこでも、次のコードは機能するはずですが、機能しません。

public async Task DoSomething(int x)
{
   try
   {
      // Asynchronous implementation.
      await Task.Run(() => {
      throw new Exception();
      x++;
      });
   }
   catch (Exception ex)
   {
      // Handle exceptions ?
   }
}

そうは言っても、私は何もキャッチしておらず、「スロー」行で発生した「未処理の例外」を取得しています。私はここで無知です。

4

5 に答える 5

14

SLaks が言ったように、あなたのコードは正常に動作します。

例を単純化しすぎてasync void、コードに が含まれている可能性が高いと思います。

以下は正常に動作します

private static void Main(string[] args)
{
    CallAsync();
    Console.Read();
}

public static async void CallAsync()
{
    try
    {
        await DoSomething();
    }
    catch (Exception)
    {
        // Handle exceptions ?
        Console.WriteLine("In the catch");
    }
}

public static Task DoSomething()
{
    return Task.Run(() =>
    {
        throw new Exception();
    });
}

以下は機能しません:

private static void Main(string[] args)
{
    CallAsync();
    Console.Read();
}

public static void CallAsync()
{
    try
    {
        DoSomething();
    }
    catch (Exception)
    {
        // Handle exceptions ?
        Console.WriteLine("In the catch");
    }
}

public static async void DoSomething()
{
    await Task.Run(() =>
    {
        throw new Exception();
    });
}

http://msdn.microsoft.com/en-us/magazine/jj991977.aspxを参照してください。

Async void メソッドには、異なるエラー処理セマンティクスがあります。async Task または async Task メソッドから例外がスローされると、その例外がキャプチャされ、Task オブジェクトに配置されます。async void メソッドには Task オブジェクトがないため、async void メソッドからスローされた例外は、async void メソッドの開始時にアクティブだった SynchronizationContext で直接発生します。図 2 は、async void メソッドからスローされた例外を自然にキャッチできないことを示しています。

于 2013-11-08T18:10:38.553 に答える
8

x++;ステートメントに到達できないため、現時点ではコードはきれいにコンパイルされません。常に警告に注意してください。

ただし、それを修正した後、正常に動作します。

using System;
using System.Threading.Tasks;

class Test
{
    static void Main(string[] args)
    {
        DoSomething(10).Wait();
    }

    public static async Task DoSomething(int x)
    {
        try
        {
            // Asynchronous implementation.
            await Task.Run(() => {
                throw new Exception("Bang!");
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine("I caught an exception! {0}", ex.Message);
        }
    }
}

出力:

I caught an exception! Bang!

(上記のコードを WinForms アプリで試すと、UI スレッドに戻る必要があるタスクを待機しているため、デッドロックが発生することに注意してください。コンソール アプリではタスクとして問題ありませんスレッドプール スレッドで再開します。)

問題は実際にはデバッグの問題であると思われます。デバッガーは、処理されていても、処理されていないと見なす場合があります

于 2013-11-08T18:02:22.797 に答える
-1

を使用する代わりに、プロパティawaitにアクセスし、そのアクセスを &で囲みます。こちらの例に従って、そのスタイルを試すこともできます。Task.Resulttrycatch

タスク スレッドのコンテキスト内でスローされたすべての例外は、AggregateException.

于 2013-11-08T17:59:47.530 に答える