2014-04-01 2 views
1
여기

있습니다 내 프로젝트 요구 사항이 완료 될 때 ConcurrentDictionary 에서 나사를 제거하는 방법 : WCF 서비스를 호스팅 스레드가

  1. Windows 서비스.
  2. WCF 서비스는 많은 스레드를 시작하고 추적해야합니다.
  3. 각 스레드는 제공된 키로 식별 할 수 있어야합니다.
  4. 여러 가지 유형의 작업 (스레드)이 있으며 각 유형은 동일한 유형의 다른 작업이 완료 될 때까지 대기열의 추가 작업과 함께 "한 번에 최대 실행"제한이 있습니다. 내가 지금까지 무엇을 가지고

: (http://msdn.microsoft.com/en-us/library/ms733069(v=vs.110).aspx 유사) WCF 서비스를 호스팅

  1. Windows 서비스.
  2. 스레드가 포함 된 추상 클래스 (스레드를 확장 할 수 없기 때문에 컴포지션 사용)
  3. WCF 서비스 클래스에서 ConcurrentDictionary가 포함 된 MyThreadPool이라는 클래스의 정적 인스턴스가 실행중인 스레드의 레코드를 유지합니다.

내 질문은 :

  1. 이 (스레드의 완료에) 스레드 목록에서 완성 된 스레드를 제거하는 가장 좋은 방법은 무엇입니까?
  2. 이 시나리오에서 ConcurrentDictionary의 정적 인스턴스가 스레드를 관리하는 좋은 방법입니까? 그렇지 않다면 무엇을 권할 수 있습니까?

내 코드의 일부는 다음과 같습니다 : 그것은 모든 의미있는 작업을 수행 한 후

[ServiceContract(Namespace = "...")] 
public interface IMyService  
{ 
    [OperationContract] 
    void StartProcess(int MIndexId, int MProcessId); 
    [OperationContract] 
    void StopProcess(int MIndexProcessId); 
} 

public class MyService : IMyService 
{ 
    private static MyThreadPool threadPool = new MyThreadPool(); 

    public void StopProcess(int MIndexProcessId) 
    { 
     throw new NotImplementedException(); 
    } 

    public void StartProcess(int ItemIdToProcess, int ProcessTypeId) 
    { 
     // call threadPool.LaunchThread(...) 
    } 
} 

public class MyThreadPool 
{ 
    private ConcurrentDictionary<int, BaseThread> _threads; 
    ... 
    public void LaunchThread(BaseThread thread, int ItemIdToProcess) 
    { 
     // set additional data for thread (such as a key and name) for tracking in a database 
     _threads.AddOrUpdate(ItemIdToProcess, thread, (key, oldValue) => { return  oldValue; }); 
     thread.Start(); 
    } 
    public void KillThread(int ItemIdToProcess) 
    { 
     ... 
    } 
} 

public abstract class BaseThread 
{ 
    // some additional properties for tracking thread 
    // ... 
    private Thread _thread; 

    protected BaseThread() 
    { 
     _thread = new Thread(new ThreadStart(this.RunThread)); 
     _thread.IsBackground = true; 
    } 
    // Thread methods/properties 
    public void Start() { _thread.Start(); } 
    public void Join() { _thread.Join(); } 
    public bool IsAlive { get { return _thread.IsAlive; } } 
    public string Name 
    { 
     get 
     { 
      return _thread.Name; 
     } 
     set 
     { 
      _thread.Name = value; 
     } 
    } 
    public void Abort() 
    { 
     _thread.Abort(); 
    } 
    public abstract void RunThread(); 
} 

public class ValidateThread : BaseThread 
{ 
    public override void RunThread() 
    { 
     ... 
     // indicate to calling thread to remove from thread list(); 
    } 
} 
+0

귀하의 질문에 답변했습니다. 더 구체적으로해야 할 문제는 무엇입니까? – usr

+0

일반적으로 WCF 스레딩 기능으로는 다루지 않는 특별한 요구 사항이없는 한 자체 ThreadPool을 작성하는 것은 좋지 않습니다. 이 질문에 대한 답변보기 : http://stackoverflow.com/questions/3295045/does-wcf-support-multi-threading-itself –

답변

3
  1. 스레드가 자체를 제거합니다. 더 나아가 LongRunning 옵션과 함께 Task을 사용하십시오. 작업 작성이 쉽습니다.
  2. 합리적인 것 같습니다. 이미 많은 함정을 피하고 디자인이 탄탄 해 보입니다. IIS에서 호스팅되는 WCF 서비스의 함정 중 하나는 언제든지 작업자 프로세스가 종료 될 수 있다는 것입니다. Windows 서비스를 사용하여이를 피할 수 있습니다.

Windows 서비스는 대부분 외부에서 시작된 exe입니다.

그래도 좋지 않은 한 가지는 다음과 같습니다. _thread.Abort();Thread.Abort is evil. 취소 이어야하며 (안해야 함 :해야 함) .NET에서 협조해야합니다.

+0

감사. 내 WCF 서비스가 IIS에서 호스팅되지 않습니다. Windows 서비스에서 호스팅됩니다. 특정 스레드에서 "스레드를 스스로 제거"할 수 있습니까? ConcurrentDictionary에 대한 참조를 각 스레드에 전달한 다음 해당 스레드에서 ConcurrentDictionary를 제거해야합니까? – Stu

+0

예.아키텍처에서 필요로하는 경우 스레드가 작업을 완료 할 때 호출 할 콜백을 제공 할 수 있습니다. 그런 식으로 스레드는 중앙 레지스트리에 대해 아무 것도 알 필요가 없습니다.; 또는 작업을 사용하는 경우 연속을 첨부하십시오. 그런 식으로 주요 작업은 중앙 레지스트리에 대해 알 필요가 없습니다. – usr

관련 문제