我以前使用过BeginAccept()和BeginRead(),但与Visual Studio 2012我想利用新的异步的(async,await)功能在我的socket服务器程序.
我该如何完成AcceptAsync和ReceiveAsync功能?
using System.Net;
using System.Net.Sockets;
namespace OfficialServer.Core.Server
{
public abstract class CoreServer
{
private const int ListenLength = 500;
private const int ReceiveTimeOut = 30000;
private const int SendTimeOut = 30000;
private readonly Socket _socket;
protected CoreServer(int port, string ip = "0.0.0.0")
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Bind(new IPEndPoint(IPAddress.Parse(ip), port));
_socket.Listen(ListenLength);
_socket.ReceiveTimeout = ReceiveTimeOut;
_socket.SendTimeout = SendTimeOut;
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); …Run Code Online (Sandbox Code Playgroud) 我想有一个通用的可重用的代码为包装EAP模式的任务,类似什么东西Task.Factory.FromAsync了呢BeginXXX/EndXXXAPM模式.
例如:
private async void Form1_Load(object sender, EventArgs e)
{
await TaskExt.FromEvent<EventArgs>(
handler => this.webBrowser.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(handler),
() => this.webBrowser.Navigate("about:blank"),
handler => this.webBrowser.DocumentCompleted -=
new WebBrowserDocumentCompletedEventHandler(handler),
CancellationToken.None);
this.webBrowser.Document.InvokeScript("setTimeout",
new[] { "document.body.style.backgroundColor = 'yellow'", "1" });
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,它看起来像这样:
public static class TaskExt
{
public static async Task<TEventArgs> FromEvent<TEventArgs>(
Action<EventHandler<TEventArgs>> registerEvent,
Action action,
Action<EventHandler<TEventArgs>> unregisterEvent,
CancellationToken token)
{
var tcs = new TaskCompletionSource<TEventArgs>();
EventHandler<TEventArgs> handler = (sender, args) =>
tcs.TrySetResult(args);
registerEvent(handler);
try
{
using …Run Code Online (Sandbox Code Playgroud) 在使用异步套接字的 MSDN示例中,套接字中的接收数据是通过从 BeginReceive 调用的回调处理程序中重复调用异步 BeginReceive 来完成的:
private static void ReceiveCallback( IAsyncResult ar ) {
//...Skipped...
if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
new AsyncCallback(ReceiveCallback), state);
} else {
// ...Skipped...
}
Run Code Online (Sandbox Code Playgroud)
http://msdn.microsoft.com/en-us/library/bbx2eya8(v=vs.110).aspx
是否有必要从已经在单独线程中执行的处理程序再次进行异步调用?可以简单地在此处理程序中循环使用 Receive 吗?就像是:
while (bytesRead) {
bytesRead = client.Receive(state.buffer, 0, client.Available,
SocketFlags.None);
// Etc...
}
Run Code Online (Sandbox Code Playgroud)