向休眠线程发出信号

发布于 2024-09-14 12:48:59 字数 944 浏览 0 评论 0原文

我是 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
    }
}

在本课程中,实现注释掉的短语和整体性能的最有效方法是什么?

I'm new to multithreading in c# and am confused among all thread stuff.
here is what I'm trying to have:

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
    }
}

in this class, what is the most efficient method to achieve commented out phrases and for overall performance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤君无依 2024-09-21 12:48:59

考虑使用 Monitor.Wait()监视器。脉冲()

例如:

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() 将等待当前作业完成处理。这可能不是您想要的。也许您应该有一个作业数据对象的QueueAddJob 会将一个项目入队,而Run 将保持出队直到队列为空。如果这样做,Run 中的锁定语句应仅包含对队列的访问,而不是整个处理阶段。

Consider using Monitor.Wait() and Monitor.Pulse().

For example:

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();
}

However, notice that in my code you still have only one jobData object — the consequence being that AddJob() will wait for the current job to finish processing. This may not be what you want. Perhaps you should have a Queue<T> of job data objects; AddJob would Enqueue an item and Run would keep Dequeue’ing until the queue is empty. If you do this, the lock statement in Run should encompass only the access to the queue, not the entire processing stage.

傲性难收 2024-09-21 12:48:59

我不知道性能,但看起来你想要 自动重置事件

这无疑为您提供了执行您所描述的操作的最简单方法之一。对其进行测试,如果您发现性能是一个问题,那么就考虑另一种方法来实现它。

I don't know about the performance, but it looks like you want AutoResetEvent.

This certainly gives you one of the simplest ways to do what you're describing. Test it out, and if you find performance is an issue, then worry about another way to do it.

不即不离 2024-09-21 12:48:59

在我看来,您想使用生产者/消费者模式。使用阻塞队列最容易实现这一点。一旦你有了这个,那么其他一切就很容易了。您可以在此处找到实现,或者您可以使用BlockingCollection 类在 4.0 中可用。

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

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();
    }
}

It looks to me like you want to use the producer/consumer pattern. This is most easily accomplished using a blocking queue. Once you have that then everything else is easy. You can find an implementation here or you can use the BlockingCollection class available in 4.0.

Note: Hardening code is omitted for brevity.

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文