内存泄漏,文件被另一个进程异常使用
本文关键字:进程 异常 另一个 泄漏 文件 内存 | 更新日期: 2023-09-27 17:53:42
这个应用程序似乎占用了大量内存。也许我没有妥善管理记忆。请找出哪些代码需要优化。其次,文件复制不能正常工作。它有时会抛出一个异常,不能访问另一个进程正在使用的文件,这个异常在两端被抛出,观察文件夹和我正在复制的目标文件夹。让我简要地告诉你我在这里想要达到的目标。
我有一个系统,会给我一个xml文件在ansi格式。该文件将定期更新,可能每3-4分钟,有时甚至10-20秒。现在我正在监视这个文件夹,一旦它被更改,我就将其转换为UTF-8并通过sftp将其复制到另一个服务器。这个sftp文件夹被映射到发生转换的同一台机器上。所以我面临的问题是它抛出的异常,不能访问另一个进程正在使用的文件,过了一会儿这个get就被清除了。甚至是内存异常,系统内存耗尽。它也在泄漏内存。从5k开始,几个小时后内存使用量达到1.2gb。现在我需要运行3个类似的程序来监视3个不同的文件夹。我的问题有什么线索吗?
class Test
{
class Class1
{
private static FileSystemWatcher watcher = new FileSystemWatcher();
public static void Main()
{
WatchFile();
Console.ReadLine();
}
private static void WatchFile()
{
watcher.Path = @"c:'test";
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.xml";
watcher.Changed += new FileSystemEventHandler(convert);
watcher.Error += new ErrorEventHandler(WatcherError);
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press ''q'' to quit.");
Console.WriteLine("Press ''q'' to quit.");
while (Console.Read() != 'q') ;
}
public static string CrL = "'r'n";
private static void convert(object source, FileSystemEventArgs f)
{
string FileName = f.FullPath;
string destinationFile = @"z:'xml'test.xml";
Thread.Sleep(2000);
try
{
watcher.EnableRaisingEvents = false;
Encoding utf8 = new UTF8Encoding(false);
Encoding ansi = Encoding.GetEncoding(1256);
Thread.Sleep(2000);
string xml = File.ReadAllText(FileName, ansi);
XDocument xmlDoc = XDocument.Parse(xml);
File.WriteAllText(FileName, @"<?xml version=""1.0"" encoding=""utf-8""?>" + xmlDoc.ToString(), utf8);
if (File.Exists(destinationFile))
File.Delete(destinationFile);
File.Copy(FileName, destinationFile,true);
Console.WriteLine("File Copied"); // for troubleshoooting only
Console.Write(CrL);
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
finally
{
watcher.EnableRaisingEvents = true;
}
}
private static void WatcherError(object source, ErrorEventArgs e)
{
Exception watchException = e.GetException();
watcher = new FileSystemWatcher();
while (!watcher.EnableRaisingEvents)
{
try
{
WatchFile();
Console.WriteLine("I'm Back!!");
}
catch
{
Thread.Sleep(2000);
}
}
}
}
}
WatchFile()
,这将再次将convert
和WatcherError
方法添加到Changed
和Error
调用列表中。这就解释了为什么会出现缓慢的内存泄漏。委托调用列表继续增长由于事件是在池线程上引发的,因此您的代码可能并发地处理多个已更改的事件。
Watcher.EnableRaisingEvents = true;
),当然不应该再添加事件处理程序。您还需要在convert
方法中同步访问。你可以用锁来做,但可能更好的主意是用Monitor.TryEnter
,像这样:
private static object lockObject = new Object();
private static void convert(object source, FileSystemEventArgs f)
{
if (!Monitor.TryEnter(lockObject))
{
// unable to get lock, return.
return;
}
try
{
// do stuff here
}
finally
{
Monitor.Exit(lockObject);
}