C# 异步方法调用调用同步方法调用

C# 异步方法调用调用同步方法调用,c#,.net,multithreading,asynchronous,C#,.net,Multithreading,Asynchronous,我正在开发一个线程安全类,我想将异步方法调用包装在同步方法调用周围。也许我不是在寻找“asynccall”方法的定义,而是接近它的定义。在实例上调用AsyncToStartSearchPage()时,我希望调用线程阻塞,直到新线程获得对象的锁为止。这就是信号灯的作用。asyncCalls锁用于限制使用。也许这不是最好的实现,但我觉得它需要某种方法来限制异步请求的数量。任何反馈都会很好。 应用程序的用途是我有一个消费者/生产者模型,其中调用此方法的线程将开始ToStartPage()方法调用并将其

我正在开发一个线程安全类,我想将异步方法调用包装在同步方法调用周围。也许我不是在寻找“asynccall”方法的定义,而是接近它的定义。在实例上调用AsyncToStartSearchPage()时,我希望调用线程阻塞,直到新线程获得对象的锁为止。这就是信号灯的作用。asyncCalls锁用于限制使用。也许这不是最好的实现,但我觉得它需要某种方法来限制异步请求的数量。任何反馈都会很好。 应用程序的用途是我有一个消费者/生产者模型,其中调用此方法的线程将开始ToStartPage()方法调用并将其放入缓冲区。另一方面,我希望线程在ToStartPage()完成之前获取对象,而不可能更改对象的状态。在此之前,我遇到过这样的问题:在线程的旋转能够获得锁并执行ToStartPage()之前,使用者将获得对象的锁


更清洁的替代方案可能如下所示。您不需要信号量来让调用线程等待直到获得锁。请注意,我是如何使用ManualResetEvent并为此制作了一个冗余锁构造的。一旦获得外部锁,就会发出事件信号,因为锁是可重入的,所以会立即获得内部锁。现在,我使用了一个信号量来限制AsyncToSearchPage的执行

public class YourThreadSafeClass
{
  private Object m_Lock = new Object();
  private Semaphore m_Semaphore = new Semaphore(1, 1);

  public void ToSearchPage()
  {
    lock (m_Lock)
    {
       // Actual work goes here.
    }
  }

  public bool AsyncToSearchPage()
  {
    // Throttle access using a semaphore
    if (m_Semaphore.WaitOne(0)) 
    {
      try 
      { 
        ManualResetEvent e = new ManualResetEvent(false);
        Thread t = new Thread(
            () =>
            {
              // Acquire the lock here for the purpose of signalling the event
              lock (m_Lock)
              {
                e.Set();
                ToSearchPage(); // The lock will be acquired again here...thats ok
              }
            }
          );
        t.Start();
        e.WaitOne(); // Wait for the lock to be acquired
        return true;
      }
      finally 
      {
        // Allow another thread to execute this method
        m_semaphore.Release();
      } 
    }
    return false;
  }
}

请记住,这是一个稍微干净的方法来做同样的事情。然而,我建议完全避免这种方法,因为它仍然很难看。我并不真正理解有必要限制对异步方法的访问,也不需要阻止它,直到包装的同步方法获得锁为止。相反,请考虑在.NETFramework中使用的RealXXXX/Endxxx异步模式。

< P> Spring将是它的最佳解决方案,它的@调度和@异步支持

A:这个模型会起作用吗?有什么更好的实现建议吗?你想限制异步调用,但想在此限制过程中阻止调用线程?你可能想问一个不同的问题,详细说明你的需求,并征求建议。这样行吗?大概我不想在没有彻底测试的情况下猜测某段多线程代码是否可以工作。线程a将在obj上调用AsyncToStartSearchPage(),然后再放入阻塞缓冲区,其中线程B将等待将obj从缓冲区中取出,并假设obj处于操作ToSearchPage()留下的状态。我不希望A或B等待ToSearchPage()调用,所以我希望它是异步的,以减少这种情况。这个电话可能需要几秒钟。需要更多细节吗?所以,如果线程A创建线程C来处理ToSearchPage()方法,那么线程A将obj放入缓冲区。如果A将obj放入缓冲区,B检索obj并在C获得锁之前获得锁,那么我将陷入痛苦的世界。
public class YourThreadSafeClass
{
  private Object m_Lock = new Object();
  private Semaphore m_Semaphore = new Semaphore(1, 1);

  public void ToSearchPage()
  {
    lock (m_Lock)
    {
       // Actual work goes here.
    }
  }

  public bool AsyncToSearchPage()
  {
    // Throttle access using a semaphore
    if (m_Semaphore.WaitOne(0)) 
    {
      try 
      { 
        ManualResetEvent e = new ManualResetEvent(false);
        Thread t = new Thread(
            () =>
            {
              // Acquire the lock here for the purpose of signalling the event
              lock (m_Lock)
              {
                e.Set();
                ToSearchPage(); // The lock will be acquired again here...thats ok
              }
            }
          );
        t.Start();
        e.WaitOne(); // Wait for the lock to be acquired
        return true;
      }
      finally 
      {
        // Allow another thread to execute this method
        m_semaphore.Release();
      } 
    }
    return false;
  }
}