首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

哪位高手能告诉小弟我C#中的Socket的BeginReceive内部是怎么异步的

2012-05-07 
谁能告诉我C#中的Socket的BeginReceive内部是如何异步的?我看了Socket源代码,但是不是很了解它的原理,它是

谁能告诉我C#中的Socket的BeginReceive内部是如何异步的?
我看了Socket源代码,但是不是很了解它的原理,它是就调用了WSARecv这个函数然后我不知道它是什么时候进行回调的,它是用WSAEventSelect?

public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, object state) 
  {
   
  if (CleanedUp) {
  throw new ObjectDisposedException(this.GetType().FullName); 
  } 

  // 
  // parameter validation
  //
  if (buffer==null) {
  throw new ArgumentNullException("buffer"); 
  }
  if (offset<0 || offset>buffer.Length) { 
  throw new ArgumentOutOfRangeException("offset"); 
  }
  if (size<0 || size>buffer.Length-offset) { 
  throw new ArgumentOutOfRangeException("size");
  }

  // We need to flow the context here. But we don't need to lock the context - we don't use it until the callback. 
  OverlappedAsyncResult asyncResult = new OverlappedAsyncResult(this, state, callback);
  asyncResult.StartPostingAsyncOp(false); 
 
  // Run the receive with this asyncResult.
  errorCode = DoBeginReceive(buffer, offset, size, socketFlags, asyncResult); 

  if(errorCode != SocketError.Success && errorCode !=SocketError.IOPending){
  asyncResult = null;
  } 
  else
  { 
  // We're not throwing, so finish the async op posting code so we can return to the user. 
  // If the operation already finished, the callback will be called from here.
  asyncResult.FinishPostingAsyncOp(ref Caches.ReceiveClosureCache); 
  }

  if(s_LoggingEnabled)Logging.Exit(Logging.Sockets, this, "BeginReceive", asyncResult);
  return asyncResult; 
  }

private SocketError DoBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, OverlappedAsyncResult asyncResult) 
  { 
  GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginReceive() size:" + size.ToString());
 
#if DEBUG
  IntPtr lastHandle = m_Handle.DangerousGetHandle();
#endif
  // Guarantee to call CheckAsyncCallOverlappedResult if we call SetUnamangedStructures with a cache in order to 
  // avoid a Socket leak in case of error.
  SocketError errorCode = SocketError.SocketError; 
  try 
  {
  // Set up asyncResult for overlapped WSARecv. 
  // This call will use completion ports on WinNT and Overlapped IO on Win9x.
  asyncResult.SetUnmanagedStructures(buffer, offset, size, null, false /* don't pin null RemoteEP*/, ref Caches.ReceiveOverlappedCache);

  // This can throw ObjectDisposedException. 
  int bytesTransferred;
  errorCode = UnsafeNclNativeMethods.OSSOCK.WSARecv( 
  m_Handle, 
  ref asyncResult.m_SingleBuffer,
  1, 
  out bytesTransferred,
  ref socketFlags,
  asyncResult.OverlappedHandle,


  IntPtr.Zero); 

  if (errorCode!=SocketError.Success) { 
  errorCode = (SocketError)Marshal.GetLastWin32Error(); 
  GlobalLog.Assert(errorCode != SocketError.Success, "Socket#{0}::DoBeginReceive()|GetLastWin32Error() returned zero.", ValidationHelper.HashString(this));
  } 
  GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginReceive() UnsafeNclNativeMethods.OSSOCK.WSARecv returns:" + errorCode.ToString() + " bytesTransferred:" + bytesTransferred.ToString() + " returning AsyncResult:" + ValidationHelper.HashString(asyncResult));
  }
  finally
  { 
  errorCode = asyncResult.CheckAsyncCallOverlappedResult(errorCode);
  } 
 
  //
  // if the asynchronous native call fails synchronously 
  // we'll throw a SocketException
  //
  if (errorCode != SocketError.Success)
  { 
  //
  // update our internal state after this socket error and throw 
  asyncResult.ExtractCache(ref Caches.ReceiveOverlappedCache); 
  UpdateStatusAfterSocketError(errorCode);
  if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "BeginReceive", new SocketException(errorCode)); 
  asyncResult.InvokeCallback(new SocketException(errorCode));
  }
#if DEBUG
  else 
  {
  m_LastReceiveHandle = lastHandle; 
  m_LastReceiveThread = Thread.CurrentThread.ManagedThreadId; 
  m_LastReceiveTick = Environment.TickCount;
  } 
#endif

  return errorCode;
  }

[解决办法]
不知道原理 简单会用
[解决办法]
应该是多线程

[解决办法]
IO模型:异步可以支持2个,一个是重叠机制
另一个是完成端口

这个不用切换吧,

热点排行