Task Exception을 밖에서 처리하는 방법

        public static Task TCPMonitor(CancellationTokenSource source, TcpClient client)
        {
            return Task.Run(() =>
            {
                while (!source.IsCancellationRequested)
                {
                    if (client.Client.Poll(5000, SelectMode.SelectRead))
                    {
                        throw new Exception("e");
                    }
                }
            });
        }

위와 같이 Task를 만들고

                try
                {
                    TCPConnection.TCPMonitor(token, client);
                }
                catch (Exception)
                {
                    throw;
                }

이렇게 처리를 하고 싶은데요. 여러가지 방법을 사용해봤는데 Exception이 handling 되지 않습니다. ㅠㅠ
Exception을 어떻게 밖에서 처리할 수 있을까요

1개의 좋아요

제시한 코드 구조로는 불가능 합니다. 제가 밖에 있어서 다른 분이 보완 답변 주시면 감사하겠습니다.


먼저 이것을 살펴보시고 예외를 감지할 수 있는 시점을 확인 바랄께요.

4개의 좋아요

@dimohy 님이 링크 주신곳에 답이 있는거 같습니다.

public void TCPMonitor(CancellationTokenSource source, TcpClient client)
        {
            while (!source.IsCancellationRequested)
            {
                if (client.Client.Poll(5000, SelectMode.SelectRead))
                {
                    throw new Exception("e");
                }
            }
        }
 _ = Task.Run(() =>
            {
                TCPMonitor(token, client);

            }).ContinueWith(_ =>
            {
                if (_.Exception?.InnerException is { } inner)
                {
                    Console.WriteLine("{0}: {1}",
                        inner.GetType().Name,
                        inner.Message);
                }
            });
3개의 좋아요

안녕하세요~

원하시는대로는 Task에서 나온 예외를 잡을 수 없습니다…

2가지 정도 방법이 떠올라서 전달 드립니다.

await를 붙이면 예외를 잡을 수 있습니다.

비동기 코드지만 동기 코드처럼 catch할 수 있습니다.

private async void button1_Click(object sender, EventArgs e)
{
    try
    {
        await TaskFuncAsync(); 
    }
    catch (Exception ex)
    {
    }
}

private async Task TaskFuncAsync()
{
    await Task.Run(() =>
    {
        throw new Exception("e");
    });
}

Task에 ContinueWith()를 사용한다.

Task객체가 끝난 후 반환값을 확인하는 방법입니다.
개인적으론 await 등장전엔 이 방법을 자주 사용했지만 await 등장 후 잘 사용하지 않는 패턴입니다.

  private void button3_Click(object sender, EventArgs e)
  {
      TaskFunc().ContinueWith(x =>
      {
          if (x.Exception != null)
          {
              // 예외가 있으면 여기 잡힘
          }
      });
  }

  private Task TaskFunc()
  {
      return Task.Run(() =>
      {
          throw new Exception("e");
      });
  }

이 방법이 아니라면… 함수를 호출하는 측에서 예외를 처리 하는 것이 아니라
직접 함수 안에서 try-catch를 사용하는 방법이 있을 것 같습니다.

도움이 되셨으면 좋겠네요!

6개의 좋아요