반응형

출처 : MSDN : https://docs.microsoft.com/ko-kr/dotnet/standard/threading/cancellation-in-managed-threads

 

관리되는 스레드의 취소

관리되는 스레드의 취소Cancellation in Managed Threads 이 문서의 내용 --> .NET Framework 4부터 .NET Framework에서는 비동기 또는 장기 실행 비동기 작업의 협조적 취소를 위한 통합 모델을 사용합니다.Starting with the .NET Framework 4, the .NET Framework uses a unified model for cooperative cancellation of asynchron

docs.microsoft.com

우리가 비동기 함수를 호출할 때 가령 socket의 accept를 비동기로 호출한 후

서버 가동을 중지할 때 해당 Accept를 중지하는 경우 등등 해당 비동기 함수에 대하여

작업을 취소해야하는 경우가 있을 수 있다.

 

이런 경우 해당 함수에 대하여 직접적인 접근을 할 수도 있겠지만

단순히 중지를 알림으로써 해결할 수도 있을 것이다.

이와 관련하여 사용할 수 있는것이 CancellationTokenSource와 CancellationToken이다.

 

이해한 바에 따르면 우선 Token의 경우 구조체이기 때문에 값복사가 이루어진다.

이러한 토큰은 TokenSource의 인스턴스가 제공하는 CancellationTokenSource.Token의 반환값을 사용하며,

이 token을 각각의 "취소요청을 수신할 스레드"에 전달한다.

물론 위의 스레드, 작업(Task)의 경우 token이 최소된 경우 처리할 로직을 구현해야한다.

더불어 만약 TokenSource가 Token외 별도의 리소스를 지닌 상태라면

해당 리소스에 관한 처리도 Dispose에서 처리해줘야 한다.

 

MSDN에서 제공한 소스코드 예제를 보자.

using System;
using System.Threading;

public class Example
{
   public static void Main()
   {
      // Create the token source.
      CancellationTokenSource cts = new CancellationTokenSource();

      // Pass the token to the cancelable operation.
      ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), cts.Token);
      Thread.Sleep(2500);

      // Request cancellation.
      cts.Cancel();
      Console.WriteLine("Cancellation set in token source...");
      Thread.Sleep(2500);
      // Cancellation should have happened, so call Dispose.
      cts.Dispose();
   }

   // Thread 2: The listener
   static void DoSomeWork(object obj)
   {
      CancellationToken token = (CancellationToken)obj;

      for (int i = 0; i < 100000; i++) {
         if (token.IsCancellationRequested)
         {
            Console.WriteLine("In iteration {0}, cancellation has been requested...",
                              i + 1);
            // Perform cleanup if necessary.
            //...
            // Terminate the operation.
            break;
         }
         // Simulate some work.
         Thread.SpinWait(500000);
      }
   }
}
// The example displays output like the following:
//       Cancellation set in token source...
//       In iteration 1430, cancellation has been requested...

위에서 보이듯이 TokenSource인 cst가 cancel함수를 호출한 경우

DoSomeWork의 인자로 들어간 token의 IsCancellationRequest가 바뀐다.

이 때 token이 IsCancellationRequested가 한번 true로 변경될 시 다시 false로 바꿀 수 없다.

 

또 다른 활용법으로는 취소 요청이 호출된 순간에 처리할 작업을 지정하는것도 가능하다.

using System;
using System.Threading;

class CancelableObject
{
   public string id;
   
   public CancelableObject(string id)
   {
      this.id = id;
   }
   
   public void Cancel() 
   { 
      Console.WriteLine("Object {0} Cancel callback", id);
      // Perform object cancellation here.
   }
}

public class Example
{
   public static void Main()
   {
      CancellationTokenSource cts = new CancellationTokenSource();
      CancellationToken token = cts.Token;

      // User defined Class with its own method for cancellation
      var obj1 = new CancelableObject("1");
      var obj2 = new CancelableObject("2");
      var obj3 = new CancelableObject("3");

      // Register the object's cancel method with the token's
      // cancellation request.
      token.Register(() => obj1.Cancel());
      token.Register(() => obj2.Cancel());
      token.Register(() => obj3.Cancel());

      // Request cancellation on the token.
      cts.Cancel();
      // Call Dispose when we're done with the CancellationTokenSource.
      cts.Dispose();
   }
}
// The example displays the following output:
//       Object 3 Cancel callback
//       Object 2 Cancel callback
//       Object 1 Cancel callback

위 코드에서 보이듯이 해당 token에 Register 함수를 통해 token에 취소 요청이 올 경우 처리할 작업을 등록할 수 있다.

 

이 외에 Exception 을 활용한 방법도 존재하며 이방법에 대해서는 아래의 링크를 참고하면 된다.

https://docs.microsoft.com/ko-kr/dotnet/standard/parallel-programming/task-cancellation

 

작업 취소

작업 취소Task Cancellation 이 문서의 내용 --> System.Threading.Tasks.Task 및 System.Threading.Tasks.Task 클래스는 .NET Framework에서 취소 토큰을 사용하는 방법으로 취소 기능을 지원합니다. The System.Threading.Tasks.Task and System.Threading.Tasks.Task classes support cancellation through the use

docs.microsoft.com

 

 

반응형

'개발언어 > C#' 카테고리의 다른 글

Thread와 Task  (0) 2021.06.20
ThreadStatic 과 ThreadLocal  (0) 2019.11.28
알아두면 어쩌다 쓸것같은 Attribute들-1  (0) 2019.09.05
async, await란  (0) 2019.08.11
Posted by Sweetmeats_boy

블로그 이미지
Sweetmeats_boy

태그목록

Yesterday
Today
Total

달력

 « |  » 2024.9
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함