发出睡眠信号的信号

时间:2010-08-14 23:19:44

标签: c# multithreading events triggers

我是c#中多​​线程的新手,并且在所有线程中都很困惑。 这就是我想要的:

public class TheClass
{
    Thread _thread;
    bool _isQuitting;
    bool _isFinished;
    object jobData;
    public void Start()
    {
        jobData = new object();
        _thread = new Thread(new ThreadStart(Run));
        _thread.Start();
    }
    private void Run()
    {
        while (!_isQuitting)
        {
            lock (jobData) // or should i use mutex or monitor?
            {
                DoStuff();
            }
            // sleep till get triggered
        }
        DoCleanupStuff();
        _isFinished = true;
    }

    public void AddJob(object param)
    {
        jobData = param;
        //wake up the thread
    }
    public void Stop()
    {
        _isQuitting = true;
        //wake up & kill the thread
        //wait until _isFinished is true
        //dispose the _thread object
    }
}

在本课程中,实现评论短语和整体表现的最有效方法是什么?

3 个答案:

答案 0 :(得分:2)

考虑使用Monitor.Wait()Monitor.Pulse()

例如:

object locker = new object();

private void Run()
{
    while (!_isQuitting)
    {
        lock (locker)
        {
            Monitor.Wait(locker);
            DoStuff(jobData);
        }
    }
    DoCleanupStuff();
}

public void AddJob(object param)
{
    // Obtain the lock first so that you don’t
    // change jobData while the thread is processing it
    lock (locker)
    {
        jobData = param;
        Monitor.Pulse(locker);
    }
}

public void Stop()
{
    lock (locker)
    {
        _isQuitting = true;
        Monitor.Pulse(locker);
    }

    // Wait for the thread to finish — no need for _isFinished
    _thread.Join();
}

但是,请注意,在我的代码中,您仍然只有一个jobData对象 - 结果是AddJob()将等待当前作业完成处理。这可能不是你想要的。也许你应该有Queue<T>个工作数据对象; AddJobEnqueue一个项目,而Run会保留Dequeue,直到队列为空。如果这样做,Run中的lock语句应仅包含对队列的访问,而不是整个处理阶段。

答案 1 :(得分:0)

我不知道性能,但看起来你想要AutoResetEvent

这肯定会为您提供最简单的方法来完成您所描述的内容。测试一下,如果你发现性能是一个问题,那么就要担心另一种方法。

答案 2 :(得分:0)

在我看来,你想要使用生产者/消费者模式。使用阻塞队列最容易实现。一旦你拥有了那么其他一切都很容易。您可以找到实施here,也可以使用4.0中提供的BlockingCollection类。

注意:为简洁起见,省略了硬化代码。

public class TheClass
{
    private Thread m_Thread;
    private BlockingCollection<object> m_Queue = new BlockingCollection<object>();
    private CancellationTokenSource m_Cancellation = new CancellationTokenSource();

    public void Start()
    {
        m_Thread = new Thread(new ThreadStart(Run));
        m_Thread.IsBackground = true;
        m_Thread.Start();
    }

    private void Run()
    {
        while (true)
        {
            try
            {
                object job = m_Queue.Take(m_Cancellation.Token);
            }
            catch (OperationCanceledException)
            {
                break;
            }
        }
    }

    public void AddJob(object param)
    {
        m_Queue.Add(param);
    }

    public void Stop()
    {
        m_Cancellation.Cancel();
        m_Thread.Join();
    }
}
相关问题