加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 这是异步读数吗?

发布时间:2020-12-16 01:48:36 所属栏目:百科 来源:网络整理
导读:我有一个listen()函数,它正在读取网络流和一个回调函数newDataRecievedCallback. 我调用了一个方法BeginRead,它是Async,但我再次在回调函数中调用相同的方法.那不是同步逻辑吗? 还有其他方法吗? private void listen() { networkStream.BeginRead(buffer,b
我有一个listen()函数,它正在读取网络流和一个回调函数newDataRecievedCallback.

我调用了一个方法BeginRead,它是Async,但我再次在回调函数中调用相同的方法.那不是同步逻辑吗?

还有其他方法吗?

private void listen()
    {
        networkStream.BeginRead(buffer,buffer.Length,new AsyncCallback(newDataRecievedCallback),null);
    }

    private void newDataRecievedCallback(IAsyncResult rst)
    {
        try
        {
            int recievedDataSize = tcpClient.Client.Receive(buffer);
            recievedData = convertToString(buffer,incomeDataSize);

            //End Read
            networkStream.EndRead(rst);
            cleanBuffer();
            parseXMLData(recievedData);

            //Hier I call the same async method
            networkStream.BeginRead(buffer,null);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

解决方法

如果BeginRead总是异步完成,那么在回调中再次调用它仍然是异步的.

但是,BeginRead有时会同步完成(检查IAsyncResult.CompletedSynchronously),因此当您运气不好时,您的代码很容易受到堆栈溢出的影响.例如,这可能发生在一个线程中:newDataRecievedCallback – > BeginRead – > newDataRecievedCallback – > BeginRead等等.

使用BeginRead的正确方法是使用类似于下面的模式(在Nutshell中这是来自C#4.0的code snippet).实质上,您应该始终检查方法是否同步完成,然后采取适当的行动.

void Read()            // Read in a nonblocking fashion.
{
  while (true)
  {
    IAsyncResult r = _stream.BeginRead
     (_data,_bytesRead,_data.Length - _bytesRead,ReadCallback,null);

    // This will nearly always return in the next line:
    if (!r.CompletedSynchronously) return;   // Handled by callback
    if (!EndRead (r)) break;
  }
  Write();
}

void ReadCallback (IAsyncResult r)
{
  try
  {
    if (r.CompletedSynchronously) return;
    if (EndRead (r))
    {
      Read();       // More data to read!
      return;
    }
    Write();
  }
  catch (Exception ex) { ProcessException (ex); }
}

bool EndRead (IAsyncResult r)   // Returns false if there’s no more data
{
  int chunkSize = _stream.EndRead (r);
  _bytesRead += chunkSize;
  return chunkSize > 0 && _bytesRead < _data.Length;   // More to read
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读