C# Event 内核构造 |EventWaitHandle、AutoResetEvent、 ManualResetEvent

EventWaitHandle

继承:Object->WaitHandle-> EventWaitHandle
派生:System.Threading.AutoResetEvent\System.Threading.ManualResetEvent

AutoResetEvent、 ManualResetEvent只能在进程内使用。semaphore、mutex可以跨进程和线程使用。

使用内核对象记得及时释放句柄和对象。要不会造成内存浪费。

方法:

public static System.Threading.EventWaitHandle OpenExisting (string name);

1、EventWaitHandle.OpenExisting(String eventName) 静态方法,跨进程使用。判段已知的名称的自动事件是否存在

 

public static bool TryOpenExisting (string name, out System.Threading.EventWaitHandle? result);

1、EventWaitHandle.OpenExisting(String eventName) 静态方法,跨进程使用。判段已知的名称的自动事件是否存在,存在返回true。

AutoResetEvent

只能在进程内使用。

 创建自动事件的2种方式:
  1、EventWaitHandle clearCount = new EventWaitHandle(false, EventResetMode.AutoReset);
  2、AutoResetEvent are =new AutoResetEvent(true);//默认打开自动砸门,它自能唤醒一个阻塞线程,在解除第一个阻塞后,内核将事件重置为false,所以第一次waitone()不会阻塞,第二次会阻塞。

方法:

1、EventWaitHandle.OpenExisting(String eventName) 静态方法,跨进程使用。判段已知的名称的自动事件是否存在

 用AutoResetEvent实现一个类似于metux的锁。

AutoMutex am=new AutoMutex();
for (int i = 0; i < 10; i++)
{
    new Thread(() => {
        am.Enter();
        
        Thread.Sleep(1000);
        am.Release();

    }).Start();
}

class AutoMutex
{

   static AutoResetEvent are =new AutoResetEvent(true);
    static int lockOwner=-1;//当前锁的拥有者
    static int recursionCount=-1;//迭代计数器
 
    public void Enter()
    {
       int currentcount = Environment.CurrentManagedThreadId;
        if (lockOwner == currentcount)
        {
             
            recursionCount++;
            return;
        }

      
        are.WaitOne();
        Console.WriteLine("Current Thread{0}", Environment.CurrentManagedThreadId);
        recursionCount = 1;
        lockOwner = currentcount;
    }
    public void Release()
    {
        if (lockOwner == Environment.CurrentManagedThreadId) return;
        if(--recursionCount == 0)
        {
            are.Set();
            lockOwner = -1;
        }
    


    }

    public void Dispose()
    {

        are.Close();
        are.Dispose();
    }

}

 

 


ManualResetEvent

只能在进程内使用。

创建手动事件的2种方式:
  1\EventWaitHandle clearCount =new EventWaitHandle(false, EventResetMode.ManualReset);
  2\ManualResetEvent  are =new  ManualResetEvent(true);//默认打开自动砸门,所以 waitone()不会阻塞,必须手动关闭。

方法:

1、EventWaitHandle.OpenExisting(String eventName) 静态方法,跨进程使用。判段已知的名称的自动事件是否存在

posted @ 2022-01-18 00:10  小林野夫  阅读(497)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/