次のHTTPリクエストメソッドをテストしようとしています
public async Task<HttpContent> Get(string url)
{
using (HttpClient client = new HttpClient())
// breakpoint
using (HttpResponseMessage response = await client.GetAsync(url))
// can't reach anything below this point
using (HttpContent content = response.Content)
{
return content;
}
}
ただし、デバッガーは2番目のコメントの下のコードをスキップしているようです。 Visual Studio 2015 RCを使用していますが、何かアイデアはありますか?また、[タスク]ウィンドウを確認しても何も表示されませんでした
編集:解決策を見つけた
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleTests
{
class Program
{
static void Main(string[] args)
{
Program program = new Program();
var content = program.Get(@"http://www.google.com");
Console.WriteLine("Program finished");
}
public async Task<HttpContent> Get(string url)
{
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false))
using (HttpContent content = response.Content)
{
return content;
}
}
}
}
これはC#コンソールアプリだったので、メインスレッドの終了後に終了したことがわかりました。これは、Console.ReadLine()を追加して少し待った後、リクエストが返されたためです。 C#はタスクが実行されるまで待機し、タスクが終了するまで待機しないと思っていましたが、私は間違っていたと思います。なぜこれが起こったのかについて誰かが詳しく説明できれば、それは素晴らしいことです。
Main
が終了すると、プログラムが終了します。未処理の非同期操作はキャンセルされ、その結果は破棄されます。
したがって、Main
の終了をブロックする必要があります。これは、非同期操作または他のメソッドでブロックすることで行います(たとえば、Console.ReadKey
を呼び出して、ユーザーがキーを押すまでブロックします)。
static void Main(string[] args)
{
Program program = new Program();
var content = program.Get(@"http://www.google.com").Wait();
Console.WriteLine("Program finished");
}
一般的なアプローチの1つは、例外処理も行うMainAsync
を定義することです。
static void Main(string[] args)
{
MainAsync().Wait();
}
static async Task MainAsync()
{
try
{
Program program = new Program();
var content = await program.Get(@"http://www.google.com");
Console.WriteLine("Program finished");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
非同期コードでのブロックは一般に悪い考えであることに注意してください。実行する必要があるケースは非常に少なく、コンソールアプリケーションのMain
メソッドはたまたまその1つです。