C# WinForms 应用程序最大化处理器但不做任何费力的事情!
题
我有一台带有 1.20Ghz 处理器和 1GB RAM 的上网本。
我正在其上运行一个 C# WinForms 应用程序,该应用程序以 5 分钟的间隔读取文本文件的每一行,并根据该行的内容,跳过它或将其写入 xml 文件。有时它可能会处理大约 2000 行。
当它开始执行此任务时,处理器将达到最大使用率,即 100% 使用。然而,在我的带有 2.40Ghz 处理器和 3GB RAM 的台式机上,它没有受到影响(出于明显的原因)...有什么方法可以真正显着减少这个处理器问题吗?代码并不复杂,我的编码能力也不差,而且我也不会经常打开文件、读取和写入......这一切都是一举完成的。
任何帮助非常感谢!
示例代码
***定时器......
#region Timers Setup
aTimer.Tick += new EventHandler(OnTimedEvent);
aTimer.Interval = 60000;
aTimer.Enabled = true;
aTimer.Start();
radioButton60Mins.Checked = true;
#endregion Timers Setup
private void OnTimedEvent(object source, EventArgs e)
{
string msgLoggerMessage = "Checking For New Messages " + DateTime.Now;
listBoxActivityLog.Items.Add(msgLoggerMessage);
MessageLogger messageLogger = new MessageLogger();
messageLogger.LogMessage(msgLoggerMessage);
if (radioButton1Min.Checked)
{
aTimer.Interval = 60000;
}
if (radioButton60Mins.Checked)
{
aTimer.Interval = 3600000;
}
if (radioButton5Mins.Checked)
{
aTimer.Interval = 300000;
}
// split the file into a list of sms messages
List<SmsMessage> messages = smsPar.ParseFile(smsPar.CopyFile());
// sanitize the list to get rid of stuff we don't want
smsPar.SanitizeSmsMessageList(messages);
ApplyAppropriateColoursToRecSMSListinDGV();
}
public List<SmsMessage> ParseFile(string filePath)
{
List<SmsMessage> list = new List<SmsMessage>();
using (StreamReader file = new StreamReader(filePath))
{
string line;
while ((line = file.ReadLine()) != null)
{
var sms = ParseLine(line);
list.Add(sms);
}
}
return list;
}
public SmsMessage ParseLine(string line)
{
string[] words = line.Split(',');
for (int i = 0; i < words.Length; i++)
{
words[i] = words[i].Trim('"');
}
SmsMessage msg = new SmsMessage();
msg.Number = int.Parse(words[0]);
msg.MobNumber = words[1];
msg.Message = words[4];
msg.FollowedUp = "Unassigned";
msg.Outcome = string.Empty;
try
{
//DateTime Conversion!!!
string[] splitWords = words[2].Split('/');
string year = splitWords[0].Replace("09", "20" + splitWords[0]);
string dateString = splitWords[2] + "/" + splitWords[1] + "/" + year;
string timeString = words[3];
string wholeDT = dateString + " " + timeString;
DateTime dateTime = DateTime.Parse(wholeDT);
msg.Date = dateTime;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
Application.Exit();
}
return msg;
}
public void SanitizeSmsMessageList(List<SmsMessage> list)
{
// strip out unwanted messages
// list.Remove(some_message); etc...
List<SmsMessage> remove = new List<SmsMessage>();
foreach (SmsMessage message in list)
{
if (message.Number > 1)
{
remove.Add(message);
}
}
foreach (SmsMessage msg in remove)
{
list.Remove(msg);
}
//Fire Received messages to xml doc
ParseSmsToXMLDB(list);
}
public void ParseSmsToXMLDB(List<SmsMessage> list)
{
try
{
if (File.Exists(WriteDirectory + SaveName))
{
xmlE.AddXMLElement(list, WriteDirectory + SaveName);
}
else
{
xmlE.CreateNewXML(WriteDirectory + SaveName);
xmlE.AddXMLElement(list, WriteDirectory + SaveName);
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
Application.Exit();
}
}
public void CreateNewXML(string writeDir)
{
try
{
XElement Database = new XElement("Database");
Database.Save(writeDir);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public void AddXMLElement(List<SmsMessage> messages, string writeDir)
{
try
{
XElement Database = XElement.Load(writeDir);
foreach (SmsMessage msg in messages)
{
if (!DoesExist(msg.MobNumber, writeDir))
{
Database.Add(new XElement("SMS",
new XElement("Number", msg.MobNumber),
new XElement("DateTime", msg.Date),
new XElement("Message", msg.Message),
new XElement("FollowedUpBy", msg.FollowedUp),
new XElement("Outcome", msg.Outcome),
new XElement("Quantity", msg.Quantity),
new XElement("Points", msg.Points)));
EventNotify.SendNotification("A New Message Has Arrived!", msg.MobNumber);
}
}
Database.Save(writeDir);
EventNotify.UpdateDataGridView();
EventNotify.UpdateStatisticsDB();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public bool DoesExist(string number, string writeDir)
{
XElement main = XElement.Load(writeDir);
return main.Descendants("Number")
.Any(element => element.Value == number);
}
解决方案
使用探查器和/或性能监视器和/或\\live.sysinternals.com\tools\procmon.exe
和/或ResourceMonitor以确定发生了什么事情。
其他提示
如果恒温5分钟的过程是一个后台任务,你可以利用线程优先级。
这里。
如果你做一个单独的线程的处理,改变你的计时器是一个System.Threading.Timer和使用回调事件,你应该能够在该线程比你的应用程序的其余设置较低的优先级。
在你的 ParseFile 循环中,你可以尝试添加一个 线程睡眠 和/或一个 应用程序.DoEvents() 打电话看看是否有帮助。最好在解析中在单独的线程上执行此操作,但至少您可以尝试这个简单的测试,看看它是否有帮助。
可能是在你的渔获提示消息正在运行到跨线程问题。尝试更换出来用于写入到跟踪输出。
在任何情况下,你已经张贴整个(小)程序,这将不利于你的具体建议。尝试的删除方式尸体 - 一个在同一时间,科学地 - 并试图让发生/停止发生的问题。这将帮助你找到问题,消除你的问题的不相关部分(既为自己和SO)。
您当前的处理模式是基于批次 - 做解析,然后处理这些消息,依此类推
。您很可能会减少内存开销,如果你切换到LINQ风格的“拉”的方法。
例如,你可以转换你的ParseFile()
方法是这样的:
public IEnmerable<SmsMessage> ParseFile(string filePath)
{
using (StreamReader file = new StreamReader(filePath))
{
string line;
while ((line = file.ReadLine()) != null)
{
var sms = ParseLine(line);
yield return sms;
}
}
}
的优点是,因为它是生成的每个SmsMessage可处理的,而不是解析全部的消息中的一次,然后处理所有这些,
这会降低你的存储器开销,这是用于上网本和桌面之间的性能差异的最可能的原因之一。