c# - 为什么我的小程序一直使用越来越多的 RAM 和大部分 CPU?
问题描述
我正在学习 C#,我开始学习异步编程、流和套接字之类的东西,所以我尝试尝试这些概念并制作了一个简单的程序,从技术上讲,它是两个程序,一个服务器端和一个客户端。服务器端正在等待传入连接,客户端连接到服务器,然后客户端和服务器都可以相互发送文本,文本将在另一端可见。
服务器端:
class Program
{
static void Main(string[] args)
{
var client = Conection();
while (true)
{
var task1 = Read(client.Result);
var task2 = Write(client.Result);
while (!task1.IsCompleted && !task2.IsCompleted)
{
}
}
}
async static Task<TcpClient> Conection()
{
var ip = IPAddress.Parse("127.0.0.1");
var port = 23000;
TcpListener server = new TcpListener(ip, port);
server.Start();
var client = await server.AcceptTcpClientAsync();
return client;
}
async static Task Read(TcpClient cli)
{
var stream = cli.GetStream();
var reader = new StreamReader(stream);
char[] buff = new char[64];
await reader.ReadAsync(buff, 0, buff.Length);
string text = new string(buff);
Console.WriteLine(text);
}
async static Task Write(TcpClient cli)
{
var stream = cli.GetStream();
var writer = new StreamWriter(stream);
var message = await Task.Run(() => Console.ReadLine());
writer.WriteLine(message);
writer.Flush();
}
}
客户端:
class Program
{
static void Main(string[] args)
{
IPAddress ip = IPAddress.Parse("127.0.0.1");
var client = new TcpClient();
client.Connect(ip, 23000);
var stream = client.GetStream();
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
while (true)
{
var task1 = Read(reader);
var task2 = Write(writer);
while(!task1.IsCompleted && !task2.IsCompleted)
{
}
}
}
async static Task Write(StreamWriter wr)
{
var str = await Task.Run(() => Console.ReadLine());
wr.Write(str);
wr.Flush();
}
async static Task Read(StreamReader reader)
{
var str = await reader.ReadLineAsync();
Console.WriteLine(str);
}
}
它工作正常,但是当我在任务管理器中检查时看起来有些问题,看起来在客户端,RAM 使用率不断上升而不会在从客户端或服务器端发送一些短文本后停止,并且 CPU 使用率超过 11 % 在客户端和服务器端...
我可以让这段代码在使用 RAM 和 CPU 方面更有效率吗?或者我只是以错误的方式做这一切?
解决方案
您的 while 循环看起来非常令人担忧。'While(statement){}' 将使您的代码以 CPU 能够反复检查它直到最终更改的速度检查“语句”。这很可能是导致你奇怪行为的原因。如果您想拥有这种逻辑,则可以在每次检查之间进行延迟 -
while (!task1.IsCompleted && !task2.IsCompleted)
{
await Task.Delay(100);
}
这样做可以解决您的问题,但它仍然是糟糕的编码,因为当异步任务具有内置等待方法时,您正在使用 while 循环。
您可以使用 .Wait() 来代替整个循环,这将是一个好的解决方案
while (true)
{
var task1 = Read(reader);
var task2 = Write(writer);
task1.Wait();
task2.Wait();
}
但是,我首选的解决方案是将 main 设为异步方法并等待 task1 和 task2
while (true)
{
var task1 = Read(reader);
var task2 = Write(writer);
await task1;
await task2;
}
或者如果 main 不能是异步的,那么将 Main 中的所有代码放入第二种方法(即异步)中,然后在 main 中,您只需使用 .wait 语句调用第二种方法
推荐阅读
- python - 无法使用 python 在 selenium 中选择带有 link_text 的链接
- matlab - Surfnorm 在 MATLAB 中缺少一些数据
- python - 如何让我的程序打印特定单词在网站上显示的次数?
- android - 如何在 Android 中更改密码(隐藏和显示)眼睛切换图标?
- javascript - 有没有办法获取包含当前值的表单字段的 html?
- javascript - ORMS对象关系映射中如何实现规范化
- svelte - 无法运行苗条/顺风项目
- java - Spring Batch 作业无法初始化项目阅读器(FileSystemException)(内部错误)
- visual-studio-2019 - 撤消对 Git 中一个文件的工作副本修改,在 VS 2019 中可用?
- javascript - 使用 parcel 构建浏览器 - 如何不输出 CommonJS 或 ES 模块