- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个小示例应用程序,我正在尝试让一些新的 .Net 4.0 并行扩展运行(它们非常好)。我遇到了一个(可能真的很愚蠢)OutOfMemoryException 问题。我希望将此示例插入的主要应用程序读取一些数据和大量文件,对它们进行一些处理,然后将它们写到某个地方。我遇到了一些文件变大(可能是 GB)的问题,并且担心内存,所以我想并行化导致我走上这条路的事情。
现在下面的代码在较小的文件上得到了 OOME,我想我只是遗漏了一些东西。它将读入 10-15 个文件并很好地并行写出它们,但随后它会在下一个文件中阻塞。看起来它的读写大约有650MB。我们将不胜感激。
我正在从 FileStream 读入 MemorySteam,因为这是主应用程序所需要的,我只是想在某种程度上复制它。它从各种类型的位置读取数据和文件,并将它们作为 MemoryStreams 处理。
这是使用 .Net 4.0 Beta 2,VS 2010。
namespace ParellelJob
{
class Program
{
BlockingCollection<FileHolder> serviceToSolutionShare;
static void Main(string[] args)
{
Program p = new Program();
p.serviceToSolutionShare = new BlockingCollection<FileHolder>();
ServiceStage svc = new ServiceStage(ref p.serviceToSolutionShare);
SolutionStage sol = new SolutionStage(ref p.serviceToSolutionShare);
var svcTask = Task.Factory.StartNew(() => svc.Execute());
var solTask = Task.Factory.StartNew(() => sol.Execute());
while (!solTask.IsCompleted)
{
}
}
}
class ServiceStage
{
BlockingCollection<FileHolder> outputCollection;
public ServiceStage(ref BlockingCollection<FileHolder> output)
{
outputCollection = output;
}
public void Execute()
{
var di = new DirectoryInfo(@"C:\temp\testfiles");
var files = di.GetFiles();
foreach (FileInfo fi in files)
{
using (var fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read))
{
int b;
var ms = new MemoryStream();
while ((b = fs.ReadByte()) != -1)
{
ms.WriteByte((byte)b); //OutOfMemoryException Occurs Here
}
var f = new FileHolder();
f.filename = fi.Name;
f.contents = ms;
outputCollection.TryAdd(f);
}
}
outputCollection.CompleteAdding();
}
}
class SolutionStage
{
BlockingCollection<FileHolder> inputCollection;
public SolutionStage(ref BlockingCollection<FileHolder> input)
{
inputCollection = input;
}
public void Execute()
{
FileHolder current;
while (!inputCollection.IsCompleted)
{
if (inputCollection.TryTake(out current))
{
using (var fs = new FileStream(String.Format(@"c:\temp\parellel\{0}", current.filename), FileMode.OpenOrCreate, FileAccess.Write))
{
using (MemoryStream ms = (MemoryStream)current.contents)
{
ms.WriteTo(fs);
current.contents.Close();
}
}
}
}
}
}
class FileHolder
{
public string filename { get; set; }
public Stream contents { get; set; }
}
}
最佳答案
主要逻辑似乎没问题,但如果 main 中的空 while 循环是字面意思,那么您正在消耗不必要的 CPU 周期。最好改用 solTask.Wait()。
但如果单个文件可以以千兆字节运行,您仍然会遇到至少 1 个完全保存在内存中的问题,通常是 2 个(1 个正在读取,1 个正在处理/写入。
PS1:我刚刚意识到您没有预先分配 MemStream。这很糟糕,对于一个大文件,它必须经常调整大小,这会消耗大量内存。最好使用类似的东西:
var ms = new MemoryStream(fs.Length);
然后,对于大文件,您必须考虑大对象堆 (LOH)。您确定不能将文件分成几段并进行处理吗?
PS2:你不需要构造函数参数上的引用,但这不是问题所在。
关于c# - MemoryStream 写入时出现 OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1767096/
我有一个返回 MemoryStream? 的函数。如果发生错误,则为 null。然后发现不能声明变量MemoryStream? public MemoryStream? GetResponseStre
我正在将一个结构序列化到 MemoryStream 中,我想保存和加载序列化的结构。 那么,如何将 MemoryStream 保存到文件中并从文件中加载它呢? 最佳答案 您可以使用MemoryStre
我应该调用哪个? 有必要两者都调用吗? 如果我已经调用了其中一个,另一个会抛出异常吗? 最佳答案 Close() 和 Dispose() 在 MemoryStream 上调用时,仅用于做两件事: 将对
今天我注意到 MemoryStream 有点奇怪类(class)。 .Length属性是一个 long,但是 .Capacity属性,大概应该总是 >= .Length 只是一个 int。 我知道需要
我有这样的方法: public DataObject GetClipboardData() { var result = new DataObject(); result.SetTex
好的,我看过一些文章here和 here ,但他们没有做我需要做的事情,我遇到了一些麻烦。 我正在接收一段作为内存流的加密数据。我需要以某种方式将内存流写入文件(我编写模型的方式,最好是字符串),然后
我确实看到了“PDF to Image using GhostScript. No image file has to be created”,但这只是(某种程度上)回答了我一半的问题。是否可以使用
这个问题在这里已经有了答案: Stream.Seek(0, SeekOrigin.Begin) or Position = 0 (3 个答案) 关闭 9 年前。 使用的优点或缺点是什么(或区别) m
我在一些开源代码中发现了以下结构: var mstream = new MemoryStream(); // ... write some data to mstream mstream.Close(
由于 MemoryStream 是非托管资源,它是否总是需要被处理? 鉴于: 1) A method is invoked. 2) A MemoryStream object is created (
我正在尝试使用 dotMemory 进行一个简单的测试。我希望以下测试能够通过: [Test] public void MemoryStream_is_disposed() { using (
多次使用 MemoryStream 时遇到问题。 例子: For Each XImage As XImage In pdfDocument.Pages(pageCount).Resources.Ima
在使用 MemoryStream 时,我发现自己经常将数据复制(因此复制)到临时字节数组。 我认为这有点浪费资源,因为 MemoryStream 不允许您直接访问底层字节数组。 在这种情况下,Memo
如何在 Delphi 中将“Hello World”字符串、clrf 和一些随机 10 个字节写入内存流? 最佳答案 我会考虑使用二进制编写器来完成此任务。这是一个更高级别的类,负责处理将数据获取到流
我正在使用 MemoryStream 构造一个需要发送到服务器的字节数组。我有三个问题: 1) 有没有比这更好的方法来构造字节数组? 2)为什么这段代码会在我的内存流中写入虚假内容? var se
这可能是一个非常简单的问题,我认为我所追求的只是声明新 MemoryStream 的最佳实践 以下2个样本有什么区别: MemoryStream myStream = new MemoryStream
我正在尝试压缩 XML 树并将其用作电子邮件附件。带附件的电子邮件发送成功,但创建的 zip 文件始终损坏 - 它不是有效的 zip 文件,但包含二进制数据。 问题重现如下,具体参见BuildAtta
使用sharpPDF库,我生成了一个pdf内存流,并且我想直接通过电子邮件发送它。但是 ms.Seek(.... 行给出了一个 ObjectDisposeException; Cannot acces
我有一台 2 GB 的机器。在运行我的 exe 之前,我有 1.1 GB 的可用内存。当我运行下面只有一行的 exe 时,出现内存不足异常。 我预计以下行将使用大约 6 亿字节。 MemoryStre
当您从字节数组构造 MemoryStream 时,该流是否会创建自己的副本?如果,与直接从原始数组中读取字节相比,这是否是高性能场景中的性能问题? 最佳答案 它似乎没有在文档中明确提及,但请记住,您可
我是一名优秀的程序员,十分优秀!