2016-03-21 203 views
0

的.Net标准库中我只是用手写下这段代码:单一线程执行

class SingleWorkerThread 
{ 
    private static readonly ILog _logger = LogManager.GetLogger(typeof(SingleWorkerThread)); 
    public readonly BlockingCollection<Action> tasks = new BlockingCollection<Action>(); 
    private readonly Thread thread; 

    private void executeThread() 
    { 
     _logger.InfoFormat("Starting execution"); 
     Action task; 
     while((task = tasks.Take()) != null) 
     { 
      _logger.InfoFormat("About to execute a task...", task); 
      task(); 
      _logger.InfoFormat("Completed executing task"); 
     } 
     _logger.InfoFormat("Finished execution"); 
    } 

    public SingleWorkerThread() 
    { 
     thread = new Thread(executeThread); 
    } 

    public void Start() 
    { 
     thread.Start(); 
    } 

    public void Terminate() 
    { 
     tasks.Add(null); 
    } 

    public void AddTask(Action a) 
    { 
     tasks.Add(a); 
    } 

    public void Join() 
    { 
     // Wait up to 2 seconds for thread to terminate. 
     thread.Join(2000); 
    } 
} 

我使用它,以确保任务的某一类的所有执行总是由一个单独的线程来完成。

我想避免“重新发明轮子”,如果可能的话 - 是否有一个标准的.Net“队列消耗线程”模块,我可以用它来代替上述模块?

如果没有,在我刚刚发布的代码中是否有任何“陷阱”(即错误)?

+1

A “单个线程的线程池” 似乎有点矛盾。 :) – CodingGorilla

+3

“我正在使用它来确保某个类别任务的所有执行总是由单个线程完成的。”为什么? –

+0

我认为你的方法没问题(但是我会使用'Thread' +'tasks.GetConsumingEnumerable()'和'tasks.CompleteAdding')而不是添加null动作来终止任务' – Eser

回答

0

我会为此使用Microsoft的Reactive Framework(NuGet“Rx-Main”)。

这是基本的代码:

class SingleWorkerThread : IDisposable 
{ 
    private Subject<Action> _subject; 
    private IScheduler _scheduler; 
    private IDisposable _subscription; 

    private static readonly ILog _logger = LogManager.GetLogger(typeof(SingleWorkerThread)); 

    public SingleWorkerThread() 
    { 
     _scheduler = new EventLoopScheduler() 
     _subject = new Subject<Action>(); 
     _subscription = 
      _subject 
       .ObserveOn(_scheduler) 
       .Subscribe(task => 
       { 
        _logger.InfoFormat("About to execute a task...", task); 
        task(); 
        _logger.InfoFormat("Completed executing task"); 
       }); 
    } 

    public void Dispose() 
    { 
     _subscription.Dispose(); 
    } 

    public void AddTask(Action Action) 
    { 
     _subject.OnNext(Action); 
    } 
}