Closed. This question needs to be more
focused。它当前不接受答案。
想要改善这个问题吗?更新问题,使它仅关注
editing this post的一个问题。
4年前关闭。
Improve this question
信息:
我已经为商务创建了C#控制台服务器和WinForms客户端。
(如果我错了,请纠正我,我已经做了很多研究。因此,我可能对某些主题感到困惑。)
在服务器上,我读到最好将
Socket.BegingReceive
与
AsyncCallback
方法一起使用。由于它使用了
ThreadPool
类。对客户端进行多线程处理,同时也重用线程等。(而不是在单线程设置或每个客户端线程上进行while循环。(我已经读过,它们具有我不感兴趣的特定缺点)。
基本上,我所追求的是确保如果我制作的应用突然爆炸,并且有100,000(甚至1,000,000 ?!)个人在使用该应用,同时它将为每个客户保持良好而稳定的连接。
情况:
服务器:英特尔i5 4核心:服务器在另一台服务器上处理MYSQL请求,并将其提供给以期望格式格式化的客户端。
客户端:无限的硬件资源:浏览表单以填写表单时,请求服务器提供数据。
所以我担心:假设有4个客户端连接并请求服务器处理数据,该数据大约需要5秒钟来处理MYSQL数据库(据我所知,这就像是一生的处理速度。(最坏的情况等))。如果第五个客户端连接该怎么办。这意味着ThreadPool必须创建另一个线程来保存此进程。现在将这些数字增大,然后我有100个并发客户端请求确切的长期运行方法。在4核CPU上。因此,现在ThreadPool花费了十秒或更长时间来创建所有这些新线程。
问题:编辑:缩小问题:
如何为FindPrimeNumbers调用实现异步编程。 (该方法正在数据库(如果有帮助,在另一台服务器上的MySQL)上搜索数据库以查找数字。)我该怎么做才能防止这种情况发生?我该如何使其更加直观。如何防止大负载可能造成不良的用户体验等。
须藤代码
FindPrimerNumber方法类似于数据库调用。
class Program
{
private static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private static List<Socket> clientSockets = new List<Socket>();
private static CancellationTokenSource CancelSource = new CancellationTokenSource();
private static CancellationToken CancelToken = CancelSource.Token;
private const int BUFFER_SIZE = 2048;
private const int PORT = 100;
private static readonly byte[] buffer = new byte[BUFFER_SIZE];
static void Main()
{
SetupServer();
Console.ReadLine();
CloseAllSockets();
}
private static void SetupServer()
{
serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
serverSocket.Listen(0);
serverSocket.BeginAccept(BeginAcceptCallback, null);
}
private static void CloseAllSockets()
{
foreach (Socket socket in clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
serverSocket.Close();
}
private static void BeginAcceptCallback(IAsyncResult AR)
{
Socket socket = serverSocket.EndAccept(AR);
clientSockets.Add(socket);
socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, BeginReceiveCallback, socket);
Console.WriteLine("Client connected!");
serverSocket.BeginAccept(BeginAcceptCallback, null);
}
private static void BeginReceiveCallback(IAsyncResult AR)
{
Socket current = (Socket)AR.AsyncState;
int receivedInt = current.EndReceive(AR);
byte[] received = new byte[receivedInt];
Array.Copy(buffer, received, receivedInt);
current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, BeginReceiveCallback, current);
string text = Encoding.ASCII.GetString(received);
int number = 0;
if (text.ToLower() == "exit")
{
current.Shutdown(SocketShutdown.Both);
current.Close();
clientSockets.Remove(current);
Console.WriteLine("Client Disconnected");
return;
}
else if (int.TryParse(text, out number))
{
int num = FindPrimeNumber(number);
byte[] data = Encoding.ASCII.GetBytes(num.ToString());
current.Send(data);
Console.WriteLine("Prime Number: "+num+" :Sent");
}
else
{
current.Send(Encoding.ASCII.GetBytes("Not a Command"));
}
}
//VERY LONG CPU FUNCTION
public static int FindPrimeNumber(int n)
{
//Connect to database (MySQL Database on a different server, if that makes a difference)
//Send Query
//Read Return
return queryReturn()
}
}