【问题标题】:Inform another thread, that an operation is running or finished通知另一个线程,一个操作正在运行或完成
【发布时间】:2016-03-30 13:35:10
【问题描述】:

我有一个多线程应用程序,不同的线程可能想要执行一个操作。我尝试使用 Mutex 来确保该线程在运行时不会启动操作。

System.Threading.Mutex mutex;
bool isRunning = System.Threading.Mutex.TryOpenExisting(name, out mutex);
if (!isRunning)
{
   RunMethod();
}

在我创建互斥锁的方法中,并尝试在最后释放它:

var mutex = new Mutex(true, name);
try{   
    //do stuff, it takes some time
}
finally
{
    //TODO: I want to get rid of Mutex here
}

如何摆脱互斥锁?因为即使在我调用mutex.ReleaseMutex()mutex.Close() 之后,它仍然存在并且可以找到。我如何知道该操作当前正在运行或已完成?

还有其他方法吗?

【问题讨论】:

  • 我建议使用以下事件之一:AutoResetEventManualResetEvent 而不是 Mutex。不过,这里没有足够的代码让我为您制定更正式的答案。

标签: c# multithreading mutex


【解决方案1】:

正如 CodingGorilla 所说,使用事件更容易。 我希望我能很好地理解你的问题。

这个例子展示了一些事件技术:

  • 已开始等待线程。
  • 使用等待多个事件(WaitHandle.WaitAny())
  • 如何安全地终止线程。
  • 无需等待即可测试事件状态(.WaitOne(0))

这是一个例子:

public class MultiThreadedExample : IDisposable
{
    private Thread _thread;
    private ManualResetEvent _terminatingEvent = new ManualResetEvent(false);
    private ManualResetEvent _runningEvent = new ManualResetEvent(false);
    private ManualResetEvent _threadStartedEvent = new ManualResetEvent(false);

    public MultiThreadedExample()
    {
        _thread = new Thread(MyThreadMethod);
        _thread.Start();
        _threadStartedEvent.WaitOne();
    }

    private void MyThreadMethod()
    {
        _threadStartedEvent.Set();
        var events = new WaitHandle[] { _terminatingEvent, _runningEvent };

        while (WaitHandle.WaitAny(events) != 0)  // <- WaitAny returns index within the array of the event that was Set.
        {
            try
            {
                // do work......
            }
            finally
            {
                // reset the event. so it can be triggered again.
                _runningEvent.Reset();
            }

        }
    }

    public bool TryStartWork()
    {
        // .Set() will return if the event was set.
        return _runningEvent.Set();
    }

    public bool IsRunning
    {
        get { return _runningEvent.WaitOne(0); }
    }

    public void Dispose()
    {
        // break the whileloop
        _terminatingEvent.Set();
        // wait for the thread to terminate.
        _thread.Join();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-15
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多