C# WaitHandle异步WaitHandle

C# WaitHandle异步WaitHandle,c#,wcf,asynchronous,C#,Wcf,Asynchronous,我正在实现一个WCF服务,它最终在一个数据库上运行一些存储过程,该数据库调用BeginExecuteReader和BeginExecuteScalar。 我无法决定需要哪个AsyncWaitHandle实现。我考虑了两种选择: 简单的一点是: public System.Threading.WaitHandle AsyncWaitHandle { get { return m_manualResentEvent; } } 它使用锁来保护m\u Manu

我正在实现一个WCF服务,它最终在一个数据库上运行一些存储过程,该数据库调用
BeginExecuteReader
BeginExecuteScalar
。 我无法决定需要哪个
AsyncWaitHandle
实现。我考虑了两种选择:

  • 简单的一点是:

    public System.Threading.WaitHandle AsyncWaitHandle
    {
        get
        {
            return m_manualResentEvent;
        }
    }
    
  • 它使用锁来保护
    m\u ManualResentEvent

    public WaitHandle AsyncWaitHandle
    {
        get
        {
            if (m_manualResentEvent!= null)
            {
                return m_manualResetEvent;
            }
            lock (ThisLock)
            {
                if (m_manualResetEvent == null)
                {
                    m_manualResetEvent = new ManualResetEvent(isCompleted);
                }
            }
            return m_manualResetEvent;
        }
    }
    

  • 更新

    正如您在评论中提到的,您正在实现IAsyncResult。我可以从微软和微软找到两个样品。在这两种情况下,他们都支持你的选择二。我只能认为这样做是因为ManualResetEvent并不总是被使用,所以它节省了资源,只在需要时创建

    原创

    就我所见,第一个线程在不丢失任何东西的情况下,线程争用(等待锁)的机会似乎较少。我假设在第一个选项中,ManualResetEvent是在构造函数中初始化的实例成员。如果是这样,我会选择第一个


    您使用该活动的可能性有多大?如果它根本不可能,那么您可能需要考虑第二个,因为它将节省您消耗资源,并且线程争用是不可能的。p> WCF无论如何都不会使用该事件,因为这会破坏任何效率增益。如果您正在执行异步以获得效率和/或可伸缩性,请不要使用等待句柄。抛出一个
    NotImplementedException

    @acarion-我担心使用第一个会导致m_ManualRecentEvent损坏/如果我有几个元素,则无法正确读取…这会发生吗?@Yakov-是类上的实例变量还是静态的?@Yakov-我接受在构造函数中初始化的选项1?可能我会在构造函数中初始化。但我不确定构造函数init是否是最佳选项-它的优点/缺点是什么?@Yakov-您希望它是一个实例变量,并且希望在构造函数中执行,否则,其他线程将调用创建ManualResetEvent的实例成员并覆盖现有的实例成员。Begin*方法用于异步使用。如果你只想阻塞等待句柄,那就违背了他们的目的。请改用同步方法。@CoryNelson您能详细解释一下(我不确定您是否理解)我正在实现wcf。在等待句柄上阻塞的替代方法是什么?作为其中的一部分,我应该定义公共类AsyncResult:IAsyncResult。IAsyncResult接口具有AsyncWaitHandle。因此我应该实现它。我正在实现的服务是异步和非阻塞的。客户要求从数据库中提供一些数据。您的目标是哪个版本的.net?如果您不需要支持3.5及以下版本,只需使用tasks-
    Task
    implements
    IAsyncResult
    @AntonTykhyy-我知道这一点。但我需要支持.net<3.5,然后获取.net源代码或反射器,看看System.net.LazyAsyncResult是如何实现的。不幸的是,它是内部的,所以你不能从中派生。另外,它与@acarlon答案中的第二个示例非常接近。据我所知,AsyncWaitHandle仅由客户端用于检查句柄是否发出信号。因此,如果使用或不使用AsyncWaitHandle,则应由客户端决定……当您说“WCF无论如何都不会使用事件”时,您能再解释一下吗?我知道WaitHandle是IAsnycResult的一部分,是否使用它取决于客户端的开发人员。请注意,客户端和服务器由一个网络协议分隔,该协议对IAsnycResult或WaitHandle一无所知。对于客户端来说,如何在服务器上生成响应并不重要。客户端和服务器当然不共享同一个WaitHandle(它们怎么可能?如果服务器是Linux PHP应用程序呢?)。这对你有意义吗?还要注意,您可以有一个同步服务器和一个异步客户端(反之亦然)。两者的实现细节之间没有依赖关系。那么谁可以使用AsyncWaitHandle-callback呢?它是IAsyncResultWCF书中谈到的fallowing(谁(可以)调用它):CalculatorClient proxy=new CalculatorClient();IAsyncResult result=proxy.BeginAdd(2,3,null,null);/*做一些工作*/result.AsyncWaitHandle.WaitOne()//这可能会阻止int sum=proxy.EndAdd(结果)//这不会阻止Debug.Assert(sum==5);proxy.Close();正如我刚才所说,客户机有自己的异步功能,由操作系统内核支持。服务器不必做任何事情。客户机可以始终对存在的每个web服务使用回调和事件。你明白我说的话吗?如果没有,请询问。