多线程 Move 文件,进程占用,如何解决?

renjunfeng 2011-07-04 12:33:37
private static Object lock1 = new object();
private static Object lock2 = new object();
static void Main(string[] args)
{
Thread thread_write = new Thread(new ThreadStart(Write));
thread_write.Start();

Thread thread_copy = new Thread(new ThreadStart(Move));
thread_copy.Start();

Thread thread_move = new Thread(new ThreadStart(Move));
thread_move.Start();

}
private static void Write()
{
while (true)
{
System.Threading.Thread.Sleep(1000);
File.WriteAllText(Path.Combine(@"D:\ConsoleAppWrite", Guid.NewGuid().ToString() + ".txt"), "Write......");
}
}
private static void Copy()
{
while (true)
{
FileInfo[] file_infos = SortFiles(@"D:\ConsoleAppWrite", "*.txt");
foreach (FileInfo fl in file_infos)
CopyFileToFolder(fl, @"D:\ConsoleAppCopy");
}
}
private static void Move()
{
while (true)
{
FileInfo[] file_infos = SortFiles(@"D:\ConsoleAppWrite", "*.txt");
foreach (FileInfo fl in file_infos)
MoveFileToFolder(fl, @"D:\ConsoleAppMove");
}
}
#region Directory Utilities
public static FileInfo[] SortFiles(string folder, string fileFilter)
{
if (Directory.Exists(folder))
{
DirectoryInfo dirInfo = new DirectoryInfo(folder);
FileInfo[] sourceFileInfo = dirInfo.GetFiles(fileFilter, SearchOption.TopDirectoryOnly);
Array.Sort(sourceFileInfo, new FileCreateTimeComparer());
return sourceFileInfo;
}
return new FileInfo[] { };
}

public static FileInfo MoveFileToFolder(FileInfo fileInfo, string destFolder)
{
string newFileFullName = Path.Combine(destFolder, fileInfo.Name);
lock (lock1)
{
if (!File.Exists(newFileFullName))
{
File.Move(fileInfo.FullName, Path.Combine(destFolder, fileInfo.Name));
}
}
return new FileInfo(newFileFullName);
}

public static void CopyFileToFolder(FileInfo fileInfo, params string[] destFolders)
{
if (destFolders != null)
{
foreach (string destFolder in destFolders)
{
string newFileFullName = Path.Combine(destFolder, fileInfo.Name);
lock (lock2)
{
if (!File.Exists(newFileFullName))
{
File.Copy(fileInfo.FullName, Path.Combine(destFolder, fileInfo.Name));
}
}
}
}
}

public static string GetBakFolder(string currentFolder, DateTime fileCreateTime)
{
string bakFolder = string.Format(@"{0}\{1}\{2}\{3}", currentFolder, fileCreateTime.Year, fileCreateTime.Month, fileCreateTime.Day);
if (!Directory.Exists(bakFolder))
{
Directory.CreateDirectory(bakFolder);
}
return bakFolder;
}
#endregion
...全文
325 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
TimZhuFaith 2011-07-04
  • 打赏
  • 举报
回复
多lock几个地方。。。明显是同步问题
garfieldzf 2011-07-04
  • 打赏
  • 举报
回复
ManualResetEvent
renjunfeng 2011-07-04
  • 打赏
  • 举报
回复
private static void Move()
{
while (true)
{
lock (lock1)
{
FileInfo[] file_infos = SortFiles(@"D:\ConsoleAppWrite", "*.txt");
foreach (FileInfo fl in file_infos)
MoveFileToFolder(fl, @"D:\ConsoleAppMove");
}
}
}
照样是: 进程占用,不能解决问题!
bdmh 2011-07-04
  • 打赏
  • 举报
回复
你的互斥应该放到Move函数中,否则,其他线程会对你获取的文件信息进行更改
renjunfeng 2011-07-04
  • 打赏
  • 举报
回复
lock (lock1)
{
if (!File.Exists(newFileFullName))
{
File.Move(fileInfo.FullName, Path.Combine(destFolder, fileInfo.Name));
}

不起作用,如何互斥?
bdmh 2011-07-04
  • 打赏
  • 举报
回复
你连个互斥都么有,肯定出错多个线程同时搞一个目录(文件),能不出错吗
winner2050 2011-07-04
  • 打赏
  • 举报
回复
多线程对于磁盘的文件移动操作的意义在于,当文件被占用或者不存在的情况下移动就会异常,这样就很慢了。

现在你把多线程给磁盘操作带来新的异常。
renjunfeng 2011-07-04
  • 打赏
  • 举报
回复
咋就没有人 提个 解决方案呢!@我的测试代码以上!实在是找不到办法
ycproc 2011-07-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 timzhufaith 的回复:]

多lock几个地方。。。明显是同步问题
[/Quote]
还lock 越多越出问题

先检查执行顺序
renjunfeng 2011-07-04
  • 打赏
  • 举报
回复
哈哈!能lock的地方都 lock了,就是不行!

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧