【问题标题】:TCPlistener.BeginAcceptSocket - async questionTCPlistener.BeginAcceptSocket - 异步问题
【发布时间】:2010-12-16 18:57:01
【问题描述】:

前段时间我付钱给一个程序员做多线程服务器。与此同时,我已经学习了一点 C#,现在我想我可以看到减速问题 - 那个人告诉我,主线程(Form)上没有处理任何东西,所以它不能被冻结..但它是。 但我认为虽然BeginAcceptSocket 是异步操作,但它的回调在主线程上运行,如果有锁定,这就是应用程序冻结的原因。我说的对吗? 谢谢

    this.mTcpListener.BeginAcceptSocket(this.AcceptClient, null);
  protected void AcceptClient(IAsyncResult ar)
        {
            //some locking stuff
        }

【问题讨论】:

    标签: c# multithreading forms tcplistener


    【解决方案1】:

    只要您的代码获得锁,然后执行您可能遇到瓶颈的事情,调用 BeginAcceptSocket 的线程就不会被阻塞,并且可以继续工作,直到回调事件发生。在此之前它不会执行回调处理程序,因此在您的示例中,在客户端联系它之前不会发生任何锁定。如果此时执行的任何操作都需要时间或由于通信问题而延迟,它仍然可能会挂在接受代码中,但如果是这种情况,则很难从您的代码示例中判断。

    【讨论】:

    • 抱歉,您误解了这个问题。我在问我是否正确 AcceptClient 方法在主线程中运行,而不是异步。所以如果有锁,它会冻结主应用程序(Form)。
    【解决方案2】:

    不,AcceptClient()不会在主线程上运行。

    最好显示一些“锁定的东西”。

    【讨论】:

    • 真的吗?我认为回调是在调用异步操作的线程上运行的。
    • Petr,一方面:回调如何“闯入”原始线程?
    • 是的,这是真的..出于某种原因,我在想第一个线程一直等到回调被调用...没有异步 :D 你当然是对的
    【解决方案3】:

    我做了一个小的 winapp 测试,结果是即使在同一个类中声明了“AcceptClient”方法,但这个委托是从除主 winform 应用程序线程之外的其他线程调用的,因此没有阻塞。

    【讨论】:

      【解决方案4】:

      Begin/End异步IO方法使用ThreadPool线程执行回调委托,除非操作可以立即完成;在这种情况下,它会在调用线程上同步执行。

      来自Calling Synchronous Methods Asynchronously

      将回调方法的委托传递给 BeginInvoke。当异步调用完成时,该方法在 ThreadPool 线程上执行。回调方法调用 EndInvoke。

      回调不应经常发生在 GUI 线程上。 如果应用程序窗口变得无响应,可能是由于在 GUI 线程上过度调用方法造成的 - 通常是为了更新控件。

      【讨论】:

        【解决方案5】:

        AcceptClient(IAsyncResult ar) 回调可以同步完成。

        我猜如果BeginAccept 遇到新的客户端它可以同步执行回调方法。

        为了确保您必须在应用程序冻结时停止调试器并查看主(事件)线程在做什么。

        通常最好有单独的线程来执行任何 I/O。

        【讨论】:

          猜你喜欢
          • 2018-12-09
          • 2017-12-31
          • 1970-01-01
          • 2014-10-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多