Вот мой код:Ловля исключения асинхронного в основном потоке
using System;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
namespace TestAsync
{
class Program
{
private const string conn = "Data Source=UNREACHABLESERVER;Initial Catalog=master;Integrated Security=True";
static void Main(string[] args)
{
try
{
TestConnection();
}
catch
{
Console.WriteLine("Caught in main");
}
}
private static async void TestConnection()
{
bool connected = false;
using (var tokenSource = new CancellationTokenSource())
using (var connection = new SqlConnection(conn))
{
tokenSource.CancelAfter(2000);
try
{
await connection.OpenAsync(tokenSource.Token);
connected = true;
}
catch(TaskCanceledException)
{
Console.WriteLine("Caught timeout");
}
catch
{
Console.Write("Caught in function");
}
if (connected)
{
Console.WriteLine("Connected!");
}
else
{
Console.WriteLine("Failed to connect...");
throw(new Exception("hi"));
}
}
}
}
}
Выход:
Caught timeout
Failed to connect...
Но тогда моя программа завершается с необработанным исключением. Вместо этого я хочу, чтобы моя программа имела исключенное исключение в основном потоке и распечатывала Caught in main
. Как я могу сделать эту работу?
EDIT
Вот мой обновленный код, который работает так, как я хочу:
using System;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
namespace TestAsync
{
class Program
{
private const string conn = "Data Source=UNREACHABLESERVER;Initial Catalog=MyFiles;Integrated Security=True";
static void Main(string[] args)
{
try
{
TestConnection().Wait();
}
catch
{
Console.WriteLine("Caught in main");
}
Console.ReadLine();
}
private static async Task TestConnection()
{
using (var tokenSource = new CancellationTokenSource())
using (var connection = new SqlConnection(conn))
{
tokenSource.CancelAfter(2000);
await connection.OpenAsync(tokenSource.Token);
}
}
}
}
Исправить, за исключением второго предложения. Методы 'async' всегда запускаются синхронно. Однако, даже если исключение выбрасывается во время синхронной части, оно не будет передаваться вызывающему. –
@ StephenCleary: Верно, не уверен, о чем я думал. Отредактировано, чтобы это отразить. –
Я чувствую, что ваше редактирование не удовлетворило проблему @ Стивена. В частности, ваш ответ по-прежнему подразумевает, что исключение _allways_ происходит в другом потоке. Это не так. В частности, даже если «ожидание» завершается синхронно, так что продолжение выполняется в текущем потоке, исключение не будет наблюдаться вызывающим. Это по семантике дизайна метода async. –