我正在编写一个使用Socket的应用程序,它将非常密集,然后我真的需要使用我们在大服务器中的每个核心。我在stackoverflow中看到了问题(how to using ThreadPool to run socket thread parallel?),只有一个答案指向此MSDN Sample。
但我认为只指出如何使它并发而不是并行,这里有人问How cpu intensive is opening a socket,它看起来非常密集,有人在这里告诉它不要帮助TPL TaskFactory.FromAsync vs Tasks with blocking methods,有人教这里如何在任务中执行任务.Factory.FromAsync(Is there a pattern for wrapping existing BeginXXX/EndXXX async methods into async tasks?)。
如何保持套接字操作并行和高性能以及处理whith套接字 断开连接,半连接套接字和消息边界等问题是正常异步方式的头疼问题。如果将TPL和任务放在一起,如何处理它。
答案 0 :(得分:3)
看到:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace skttool
{
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public int bytesRead = 0;
public StringBuilder sb = new StringBuilder();
}
public class tool
{
//-------------------------------------------------
private ManualResetEvent evtConnectionDone = new ManualResetEvent(false);
private Socket skttool = null;
private bool running = false;
private StateObject state = null;
//-------------------------------------------------
toolConfig _cfg;
public tool(toolConfig cfg)
{
_cfg = cfg;
}
//-------------------------------------------------
public void socketListeningSet()
{
IPEndPoint localEndPoint;
Socket skttool;
byte[] bytes = new Byte[1024];
localEndPoint = new IPEndPoint(IPAddress.Any, _cfg.addressPort);
skttool = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
skttool.Bind(localEndPoint);
skttool.Listen(_cfg.maxQtdSockets);
}
//-------------------------------------------------
public void start()
{
running = true;
Task T1 = Task.Factory.StartNew(socketListeningSet);
T1.ContinueWith(prev =>
{
while (running)
{
evtConnectionDone.Reset();
Task<Socket> accepetChunk = Task<Socket>.Factory.FromAsync(
skttool.BeginAccept,
skttool.EndAccept,
accept,
skttool,
TaskCreationOptions.AttachedToParent);
accepetChunk.ContinueWith(accept, TaskContinuationOptions.NotOnFaulted | TaskCreationOptions.AttachedToParent);
evtConnectionDone.WaitOne();
}
});
}
//-------------------------------------------------
void accept(Task<Socket> accepetChunk)
{
state = new StateObject();
evtConnectionDone.Set();
state.workSocket = accepetChunk.Result;
Task<int> readChunk = Task<int>.Factory.FromAsync(
state.workSocket.BeginReceive,
state.workSocket.EndReceive,
state.buffer,
state.bytesRead,
state.buffer.Length - state.bytesRead,
null,
TaskCreationOptions.AttachedToParent);
readChunk.ContinueWith(read, TaskContinuationOptions.NotOnFaulted | TaskCreationOptions.AttachedToParent);
}
//-------------------------------------------------
void read(Task<int> readChunk)
{
state.bytesRead += readChunk.Result;
if (readChunk.Result > 0 && state.bytesRead < state.buffer.Length)
{
read();
return;
}
_data = doTask(_data);
Task<int> sendChunk = Task<int>.Factory.FromAsync(
state.workSocket.BeginSend,
state.workSocket.EndSend,
state.buffer,
state.bytesRead,
state.buffer.Length - state.bytesRead,
null,
TaskCreationOptions.AttachedToParent);
sendChunk.ContinueWith(send, TaskContinuationOptions.NotOnFaulted | TaskCreationOptions.AttachedToParent);
}
//-------------------------------------------------
void send(Task<int> readChunk)
{
state.workSocket.Shutdown(SocketShutdown.Both);
state.workSocket.Close();
}
//-------------------------------------------------
byte[] doTask(byte[] data)
{
return Array.Reverse(data);
}
//-------------------------------------------------
}
}
答案 1 :(得分:1)
请参阅此链接了解TPL and Traditional .NET Asynchronous Programming,它没有回答,但也许可以帮助您。有关于异步编程模型(APM)和基于事件的异步模式(EAP)
的信息