2017-05-04 1 views
0

전자 메일을 보내기위한 Web API를 만듭니다. 두 끝점부울 변수 값을 기반으로 메서드 실행 중지

이 있습니다
  1. /API/센드이 지금은 잘 작동하고, 이메일을 보내는 시작해야합니다.
  2. /api/StopMail이 방법으로 이메일 전송이 중단되면 이메일 전송이 중단되지 않습니다. 이것이 실제 문제입니다. 이 엔드 포인트에 도달했을 때 이메일을 중단하려면 어떻게해야합니까?

    public bool stop = false; 
    
        [HttpGet] 
        public void SendMail() 
        { 
         var emails = db.Emails.ToList();    
    
         foreach (var email in emails) 
         { 
          //code for sending mail here... 
    
          if (stop == true) 
           break; 
         } 
        } 
    
        [HttpGet] 
        public void StopMail() 
        { 
         stop = true; 
        } 
    
+0

(API 입력으로 거짓 동안) 이메일 전송을 중지 할 때 타이머를 중지 - 컨트롤러가 각 요청에 대해 한 번 사용하는 것입니다. –

+0

메일을 보내고 그 서비스를 싱글 톤 (싱글 톤 패턴 또는 DI 프레임 워크)으로 만드는 서비스를 만들 수 있습니다. –

+0

@ DanielA.White 그러면 어떤 접근 방식을 채택해야합니까? –

답변

0

당신은 정말 ASP.NET에 내장 된 물건에 너무 많은 고려 사항이 있다고 할 수 없다. 컨트롤러는 한 요청의 수명주기 동안 만 존재합니다. ASP.NET은 백그라운드 작업을 위해 설계되지 않았습니다.

일부 타사 라이브러리와 도움이 될 수있는 기본 제공 기능이 있습니다. QueueBackgroundWorkItem이 가장 유망한 것으로 보입니다.

Scott Hanselman은 write up on different approaches입니다.

-1

공유 컨텍스트를 허용하는 항목이 있어야합니다. 컨트롤러는 기본적으로 자체 컨트롤러를 갖습니다.

당신은 사용하려면이에 대한 공유 컨텍스트 주위에 static 래퍼 같은 것을 사용할 수 있습니다

public static class EmailSenderContext { 
    private static object _locker = new object(); 
    public static bool _canSend = true; 

    public static bool CanSend() { 
     var response = false; 
     lock(_locker) { 
      response = _canSend; 
     } 
     return response; 
    }  

    public static void ChangeSendState(bool canSend) { 
     lock(_locker) { 
      _canSend = canSend; 
     } 
    } 
} 
public class MyController { 
    [HttpGet] 
    public void SendMail() 
    { 
     var emails = db.Emails.ToList();    

     foreach (var email in emails) 
     { 
      //code for sending mail here... 

      if (!EmailSenderContext.CanSend()) 
       break; 
     } 
    } 

    [HttpGet] 
    public void StopMail() 
    { 
     EmailSenderContext.ChangeSendState(false); 
    } 

} 

마음 당신은, 이것은 단지 하나의 서버에서 작동합니다. 이 값을 전역 플래그로 사용하려면 데이터베이스를 도입하여 값을 저장해야하며, 확인할 때마다 해당 데이터베이스 값에 액세스해야합니다.

이것은 OVERLY 단순화 된 예제이며 많은 시스템에서 작동하지 않습니다. 다양한 사용 권한이없는 단일 서버에서만 실행되는 작업 프로젝트의 경우 작은 작업 인 경우 작동합니다. 다시 말하지만, 이것은 공유 된 컨텍스트이므로 모든 사용자는 값에 대한 일반 액세스 권한을 갖습니다.

+0

이것은 한 번에 한 명의 발신자 만 허용합니다. –

+0

정적 클래스 및 필드는 요청간에 공유됩니다. http://stackoverflow.com/a/195290/1251624 아마 내가 잘못 이해하고 있지만, 클래스 자체에서이 사건과 '잠금'이 주어지면 업데이트 된 시점과 다른 시점에서 읽을 수 없어야합니다. value @ DanielA.White –

+0

두 가지가 문맥이 혼란스러워 질 때 동시에'sendmail'과'stopmail'을 reqeusting한다면 말입니다. –

0

정지 플래그가 포함 된 SendMail 조작을 수행하는 데 다른 클래스를 구현하는 것이 더 나을 것입니다. 클래스는 싱글 톤으로 컨트롤러에 삽입 될 수 있으며 설명 된대로 시작/중지 작업을 지원할 수 있습니다. 다른 옵션에 대한 https://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.aspx

이 페이지에서 "서버 측 상태 관리 옵션"으로 스크롤하십시오 : 대신 내가 사용하는 것이 정지 변수 HttpApplicationState의

0

은 2 해결책이 있습니다 너의 문제. 내 질문은 왜 당신이 메일 목적을 보내는 웹 API를 요구하는 것입니다?

1 솔루션

  1. 이에 대한 Windows 서비스를 사용합니다.
  2. 언제든지 서비스를 중지 할 수 있습니다.

2 솔루션

  1. 를 사용하여 하나의 API 받아들이는 부울 변수
  2. 를 사용하여 클래스
  3. 시작에 타이머 변수를 유지 타이머 (당신은 웹 API에서 서비스를 중지 할 수 있습니다) 이메일을 보낼 때 타이머가 필요합니다 (API 입력으로 true). // 타이머 핸들러에이 코드를 추가하십시오. var emails = db.Emails.ToList();

    foreach (전자 메일의 전자 메일) {// 여기에 메일을 보내는 코드 ... // if (stop == true) break; }

  4. 당신은 당신이 좋아하지 않을 수

관련 문제