C# 一次例外,另一次不例外
我使用多线程将文件复制到另一个位置。我从需要的字节数组和dispose流中提取数据。在本例中,我使用7个线程复制3gb文件。第一个线程可以获取字节数组,但在第二个线程出现异常“System.OutOfMemoryException”C# 一次例外,另一次不例外,c#,multithreading,out-of-memory,C#,Multithreading,Out Of Memory,我使用多线程将文件复制到另一个位置。我从需要的字节数组和dispose流中提取数据。在本例中,我使用7个线程复制3gb文件。第一个线程可以获取字节数组,但在第二个线程出现异常“System.OutOfMemoryException” public void Begin() { FileStream stream = new FileStream(pathToFile, FileMode.Open); stream.Position = (threNmb - 1) * 536870
public void Begin()
{
FileStream stream = new FileStream(pathToFile, FileMode.Open);
stream.Position = (threNmb - 1) * 536870912;
BinaryReader reader = new BinaryReader(stream);
for (long i = 0; i < (length); i++)
{
source.Add(reader.ReadByte());//gives exception at i=134217728
}
reader.Dispose();
reader.Close();
stream.Dispose();
stream.Close();
}
public void Begin()
{
FileStream stream=新的FileStream(路径文件,FileMode.Open);
流位置=(threNmb-1)*536870912;
BinaryReader=新的BinaryReader(流);
用于(长i=0;i<(长度);i++)
{
source.Add(reader.ReadByte());//在i=134217728处给出异常
}
reader.Dispose();
reader.Close();
stream.Dispose();
stream.Close();
}
看起来您正在使用一个列表。这将是一种非常低效的复制数据的方法,而且使用多个线程可能会降低复制数据的效率。此外,如果您使用的是来自多个线程的单个列表,则代码已经被破坏-list
不是线程安全的。即使是这样,您也会混合来自不同线程的数据,因此无法重新组合原始数据。哦,如果不使用和语句,那么如果抛出异常,您将使文件句柄保持打开状态。换句话说,我建议你完全放弃目前的方法
相反,将文件从一个地方复制到另一个地方(假设您因某种原因无法使用),基本上应该是:
- 打开流进行读取
- 打开要写入的流
- 分配缓冲区(例如32K)
- 反复:
- 从“输入”流读入缓冲区,注意调用实际读取的数据量
- 将刚刚读取的数据写入输出流
- 循环,直到“读取”指示输入流的结束
- 关闭两个流(使用
语句)
没有必要把一切都记在记忆里。请注意,在.NET4中,使用该方法更容易实现这一点。第三步和第四步哪一步适合您。有什么例外?不使用语句的任何原因?一般来说,在一个磁盘上使用多个线程进行IO是一个坏主意——你只是在强迫它进行重击。您在这里可以实现的最大性能改进很可能是一次读取数据块,而不是大量调用ReadByte
。啊,我现在看到您有一个OutOfMemoryException
。源代码的类型是什么?(我希望你不是同时从多个线程中使用一个简单的列表
。)是的,我使用列表,我不知道我有没有其他方法,我使用了byte[],但它并没有我想要的那么大查看我的答案-之后你到底在用列表做什么?真的吗?列表中有3GB?但当我使用流读取并复制到其他位置时,其他线程将无法使用文件复制其他部分,该怎么办?@Cavidanquily耶夫:正如我所解释的,无论如何,你不应该使用多个线程复制单个文件-这只会导致磁盘抖动。您是否尝试过简单的方法,但发现它太慢了?您可能会使用异步IO,并在写入输出的同时读取输入,但我个人不会这样做,直到我证明上述方法太慢。