当前位置:编程学习 > C#/ASP.NET >>

C#大数据处理


有几百兆的二进制数据,我想把他们导入程序中绘制成图形;

假如我每次导入1K数据,绘制成图。我鼠标拖动观察的时候,怎么让观察到一半的时候,继续缓冲加载后边的数据!

--------------------编程问答-------------------- 后台线程读取数据 --------------------编程问答-------------------- 一个比较简单的方法是使用MemoryMappedFile(内存映射,http://msdn.microsoft.com/zh-cn/library/system.io.memorymappedfiles.memorymappedfile(v=vs.100).aspx)。

好处是易做图了操作系统缓存机制。
坏处是不容易重写到Linux等。 --------------------编程问答-------------------- BackgroundWorker --------------------编程问答-------------------- 使用缓存机制的机制,你读取二进制不是直接从文件中读取的,中间加一个缓存,即设置一个字节数组,把文件中二进制数据写到这个字节数组中,然后程序每次读取都从这个缓存读取字节,用后台线程往这个缓存中写数据 --------------------编程问答-------------------- MemoryMappedFile+1 --------------------编程问答-------------------- 用并发的线程做 非常快  --------------------编程问答-------------------- MemoryMappedFile+1  --------------------编程问答-------------------- 实在看不出楼主的需求与MemoryMappedFile有什么关联 --------------------编程问答-------------------- 开一个线程,双缓冲,分批加载 --------------------编程问答--------------------
引用 8 楼 sbwwkmyd 的回复:
实在看不出楼主的需求与MemoryMappedFile有什么关联


我也没看出来。有些回答是瞎灌水的。反正闲着没事,进入一个问题,一看有个高等级的用户回答了问题,于是复制粘贴,或者鹦鹉学舌下。 --------------------编程问答-------------------- --------------------编程问答-------------------- 看了各位的解答后,我想问下:

我先导入1K,拖动到一半后台线程加载后那我程序怎么把以前加载的释放掉。

只加载新导入的内容! --------------------编程问答--------------------
引用 10 楼 caozhy 的回复:
Quote: 引用 8 楼 sbwwkmyd 的回复:

实在看不出楼主的需求与MemoryMappedFile有什么关联


我也没看出来。有些回答是瞎灌水的。反正闲着没事,进入一个问题,一看有个高等级的用户回答了问题,于是复制粘贴,或者鹦鹉学舌下。


内存映射是虚拟内存的一种运用技术。
优点之一在于映射的内容可以延迟读取。内存映射建立在VMM(虚拟内存管理器)之上。VMM保证对还没有读取的内容进行加载(以一个页面4K为单位)。内核支持和4K页面意味快速读取和有效的缓存。
优点之二在于,如果内存紧张,VMM可以自动释放加载过的缓存。
其他优点还包括,大文件支持,使用方便等。
进一步可阅读(英文):http://msdn.microsoft.com/zh-cn/library/ms810613.aspx

下面的代码示范使用MemoryMappedFile来进行绘图(需DotNet4.0),示范数据为300兆的数据:

public partial class Form1 : Form
{
    public Form1()
    {
        //InitializeComponent();
        string filename = "c:\\temp\\example.dat";
        if (!File.Exists(filename))
        {
            MessageBox.Show("First run. Will create 300M example data file: " + filename);
            GenerateData(filename); 
        }
        this.memoryMappedFile = MemoryMappedFile.CreateFromFile(filename);
        this.scrollbar = new HScrollBar()
        {
            Height = 32,
            Dock = DockStyle.Bottom,
            Maximum = (int)(new FileInfo(filename).Length / 4),
        };
        this.scrollbar.ValueChanged += (sender, e) => this.Invalidate(invalidateChildren: false);
        this.Controls.Add(scrollbar);
        this.DoubleBuffered = true;
        this.Size = new Size(800, 600);
    }
    ScrollBar scrollbar;
    MemoryMappedFile memoryMappedFile;

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        int sampling = 100;
        int start = Math.Min(this.scrollbar.Value, this.scrollbar.Maximum - sampling);
        e.Graphics.DrawCurve(Pens.Black, GetPoints(start, sampling));
        e.Graphics.DrawString(start.ToString("n0"), this.Font, Brushes.DarkBlue, new Point(200, 15));
    }

    private PointF[] GetPoints(int start, int count)
    {
        List<PointF> points = new List<PointF>(count);
        using (var viewStream = memoryMappedFile.CreateViewStream(start * sizeof(float), count * sizeof(float)))
        using (var reader = new BinaryReader(viewStream))
        {
            for (int i = 0; i < count; i++)
            {
                float x = i * this.ClientRectangle.Width / 100;
                float y = reader.ReadSingle() * this.ClientRectangle.Height;
                points.Add(new PointF(x, y));
            }
        }
        return points.ToArray();
    }

    private void GenerateData(string outputFile = "c:\\temp\\my.dat", int count = 75 * 1024 * 1024)
    {
        Random random = new Random(123);
        if (!Directory.Exists(Path.GetDirectoryName(outputFile))) Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); 
        using (BinaryWriter writer = new BinaryWriter(new FileStream(outputFile, FileMode.Create)))
        {
            float last = 0.5f;
            for (int i = 0; i < count; i++)
            {
                last = last + (float)(random.NextDouble() - 0.5) / 20;
                last = Math.Max(0, Math.Min(last, 1));
                writer.Write(last);
            }
        }
    }
}
--------------------编程问答--------------------
如何判断在拖动到大约60%的时候继续加载呢? --------------------编程问答--------------------
引用 14 楼 porenasckx 的回复:
如何判断在拖动到大约60%的时候继续加载呢?


需要你的数据可以异步随机读取。 --------------------编程问答--------------------
引用 13 楼 gomoku 的回复:
内存映射是虚拟内存的一种运用技术。
优点之一在于映射的内容可以延迟读取。内存映射建立在VMM(虚拟内存管理器)之上。VMM保证对还没有读取的内容进行加载(以一个页面4K为单位)。内核支持和4K页面意味快速读取和有效的缓存。
优点之二在于,如果内存紧张,VMM可以自动释放加载过的缓存。
其他优点还包括,大文件支持,使用方便等。
进一步可阅读(英文):http://msdn.microsoft.com/zh-cn/library/ms810613.aspx

下面的代码示范使用MemoryMappedFile来进行绘图(需DotNet4.0),示范数据为300兆的数据:

首先,我无法确定楼主说的数据源是不是文件。
其次,我觉得楼主需要的是多线程,而不是实时加载数据。
再次,恕我愚昧,我实在无法理解MemoryMappedFile在楼主的需求中相对于FileStream有什么优点。 --------------------编程问答-------------------- 做内存缓冲区。

缓冲设计为一段数据区域,通过预先将需要从文件读取的数据,先行读取进来预处理好。用专门的线程负责往这个缓冲区填充数据。

主逻辑线程需要数据的时候直接从这个缓冲拿。拿了之后,给缓冲线程一个信号。这样主逻辑线程就可以直接从内存拿数据去处理。后台缓冲线程就不停装载数据。 --------------------编程问答-------------------- 楼主还不明白的话,可以找做音视频处理的兄弟请教。 --------------------编程问答-------------------- 路过,学习一下来了 --------------------编程问答-------------------- 除 --------------------编程问答--------------------
引用 18 楼 lorl2 的回复:
楼主还不明白的话,可以找做音视频处理的兄弟请教。


对,就是和视频和音频处理很相似的。 --------------------编程问答-------------------- 我的数据时二进制文件。谁有类似的Demo啊!感谢了! --------------------编程问答--------------------
引用 9 楼 caozhy 的回复:
开一个线程,双缓冲,分批加载


我想问下,如何判断在滚动条到达指定的位置时继续加载。

我想让内存中只保存需要显示的一部分数据。 --------------------编程问答--------------------
引用 23 楼 porenasckx 的回复:
Quote: 引用 9 楼 caozhy 的回复:

开一个线程,双缓冲,分批加载


我想问下,如何判断在滚动条到达指定的位置时继续加载。

我想让内存中只保存需要显示的一部分数据。


这个问题分为两方面,一个是显示的部分,按需显示。
另外一个就是你需要根据坐标建立一个数据结构,比如根据坐标做hash,保证可以快速检索到指定范围的数据,而不是每次都要全部搜索一遍。
--------------------编程问答--------------------
引用 24 楼 caozhy 的回复:
Quote: 引用 23 楼 porenasckx 的回复:

Quote: 引用 9 楼 caozhy 的回复:

开一个线程,双缓冲,分批加载


我想问下,如何判断在滚动条到达指定的位置时继续加载。

我想让内存中只保存需要显示的一部分数据。


这个问题分为两方面,一个是显示的部分,按需显示。
另外一个就是你需要根据坐标建立一个数据结构,比如根据坐标做hash,保证可以快速检索到指定范围的数据,而不是每次都要全部搜索一遍。


你说的有点深奥了我理解不了。

我现在每次异步读取固定长度的数据,然后绘制成图,滚动条左右拖动可以观察,我想让滚动条拖动到大于导入内容的80%的时候继续异步读取。。。。依次类推,每到大于80%的时候异步读取。但是我不知道怎么判断是否大于80%;我现在的滚动条最大值是文件的长度!
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,