如何限制我的.NET应用程序/ O操作? [英] How to limit I/O operations in .NET application?

查看:87
本文介绍了如何限制我的.NET应用程序/ O操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个应用程序(.NET 4.0,C#)认为:结果
1.扫描文件系统结果
2.打开和读取一些文件。

I'm developing an application (.NET 4.0, C#) that:
1. Scans file system.
2. Opens and reads some files.

该应用程序会在后台工作,并应该对磁盘使用情况的影响很小。如果他们做他们平时的任务应该不会打扰用户的磁盘使用率很高。反之,应用程序可以如果没有人是用碟片走得更快。结果
的主要问题是我不知道是因为使用API​​的I / O操作的实际数量和大小(MAPI32.DLL)读取文件。如果我问API做一些事情,我不知道它会读取多少字节来处理我的反应。

The app will work in background and should have low impact on the disk usage. It shouldn't bother users if they are doing their usual tasks and the disk usage is high. And vice versa, the app can go faster if nobody is using the disk.
The main issue is I don't know real amount and size of I/O operations because of using API (mapi32.dll) to read files. If I ask API to do something I don't know how many bytes it reads to handle my response.

所以,问题是如何监控和管理的磁盘使用情况?包括文件系统扫描和文件阅读...结果$ B由标准性能监视器工具使用$ b检查性能计数器?或者其他方法吗?

So the question is how to monitor and manage the disk usage? Including file system scanning and files reading...
Check performance counters that are used by standard Performance Monitor tool? Or any other ways?

感谢

推荐答案

使用系统.Diagnostics.PerformanceCounter 类,重视有关,你是索引的驱动器的物理磁盘计数器。

Using the System.Diagnostics.PerformanceCounter class, attach to the PhysicalDisk counter related to the drive that you are indexing.

下面是一些代码来说明,虽然其目前硬编码到C:盘。您将要改变C:取其驱动你的过程是扫描。 (这是粗略的样本代码只是为了说明性能计数器的存在 - 不要把它作为提供准确的信息 - 应始终作为只是一个指南更改您自己的目的)

Below is some code to illustrate, although its currently hard coded to the "C:" drive. You will want to change "C:" to whichever drive your process is scanning. (This is rough sample code only to illustrate the existence of performance counters - don't take it as providing accurate information - should always be used as a guide only. Change for your own purpose)

注意在%空闲时间计数器,表示该驱动器的频率做任何事情。
0%闲置表示磁盘忙,但并不一定意味着它是平出,不能传输更多的数据。

Observe the % Idle Time counter which indicates how often the drive is doing anything. 0% idle means the disk is busy, but does not necessarily mean that it is flat-out and cannot transfer more data.

与合并的%空闲时间 当前磁盘队列长度这将告诉你,如果驱动器被越来越的很忙,不能服务数据的所有请求的。作为一般原则,任何超过0意味着驱动器可能是单位出繁忙和任何超过2意味着驱动器是完全饱和。这些规则适用于SSD和HDD相当好。

Combine the % Idle Time with Current Disk Queue Length and this will tell you if the drive is getting so busy that it cannot service all the requests for data. As a general guideline, anything over 0 means the drive is probably flat-out busy and anything over 2 means the drive is completely saturated. These rules apply to both SSD and HDD fairly well.

另外,你读的任何值是在某个时间点的瞬时值。你应该做一个平均运行在几个结果,如采取每100ms平均5个读数读使用从结果的信息来作出决定之前(即等到柜台使你的下一个IO请求之前结清)。

Also, any value that you read is an instantaneous value at a point in time. You should do a running average over a few results, e.g. take a reading every 100ms and average 5 readings before using the information from the result to make a decision (i.e., waiting until the counters settle before making your next IO request).

internal DiskUsageMonitor(string driveName)
{

    // Get a list of the counters and look for "C:"

    var perfCategory = new PerformanceCounterCategory("PhysicalDisk");
    string[] instanceNames = perfCategory.GetInstanceNames();

    foreach (string name in instanceNames)
    {
        if (name.IndexOf("C:") > 0)
        {
            if (string.IsNullOrEmpty(driveName))
               driveName = name;
        }
    }


    _readBytesCounter = new PerformanceCounter("PhysicalDisk", 
                                               "Disk Read Bytes/sec", 
                                               driveName);

    _writeBytesCounter = new PerformanceCounter("PhysicalDisk", 
                                                "Disk Write Bytes/sec", 
                                                driveName);

    _diskQueueCounter = new PerformanceCounter("PhysicalDisk", 
                                               "Current Disk Queue Length", 
                                               driveName);

    _idleCounter = new PerformanceCounter("PhysicalDisk",
                                          "% Idle Time", 
                                          driveName);
    InitTimer();
}

internal event DiskUsageResultHander DiskUsageResult;

private void InitTimer()
{
    StopTimer();
    _perfTimer = new Timer(_updateResolutionMillisecs);
    _perfTimer.Elapsed += PerfTimerElapsed;
    _perfTimer.Start();
}

private void PerfTimerElapsed(object sender, ElapsedEventArgs e)
{
    float diskReads = _readBytesCounter.NextValue();
    float diskWrites = _writeBytesCounter.NextValue();
    float diskQueue = _diskQueueCounter.NextValue();
    float idlePercent = _idleCounter.NextValue();

    if (idlePercent > 100)
    {
        idlePercent = 100;
    }

    if (DiskUsageResult != null)
    {
        var stats = new DiskUsageStats
                        {
                                DriveName = _readBytesCounter.InstanceName,
                                DiskQueueLength = (int)diskQueue,
                                ReadBytesPerSec = (int)diskReads,
                                WriteBytesPerSec = (int)diskWrites,
                                DiskUsagePercent = 100 - (int)idlePercent
                        };
        DiskUsageResult(stats);
    }
}

这篇关于如何限制我的.NET应用程序/ O操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆