在C#asp.net中使用不安全的代码

时间:2013-06-20 07:06:31

标签: c# asp.net performance unsafe system.diagnostics

尝试调试修改后的代码以使用unsafe会产生错误 我不知道我的代码是否与astrics正确(所以请检查我是否正确使用了这些)虽然还有另外一个问题... asp.net 中的编译器选项 与Windows应用程序相反,没有可用的地方可以检查/取消选中使用不安全的选项

并且据我所知,可以获得有关处理Web的信息.Config"手动"

所以我这样做,为Web.Config添加了一个代码, 有两个版本的用户建议将代码放在配置部分或debug=true的同一范围内......

所以我把它放在两个(不是同时,但尝试了两个(:

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
 <system.codedom>
   <compilers>
     <compiler language="C#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   </compilers>
  </system.codedom>
  <connectionStrings>....my secret connection here...
   then rest of configs..
     .....




    struct IO_COUNTERS
    {
        public ulong ReadOperationCount;
        public ulong WriteOperationCount;
        public ulong OtherOperationCount;
        public ulong ReadTransferCount;
        public ulong WriteTransferCount;
        public ulong OtherTransferCount;
    }
    [DllImport("kernel32.dll")]
    unsafe static extern bool GetProcessIoCounters(IntPtr* ProcessHandle, out IO_COUNTERS* IoCounters);


    private struct PROCESS_MEMORY_COUNTERS
    {
        public uint cb;
        public uint PageFaultCount;
        public uint PeakWorkingSetSize;
        public uint WorkingSetSize;
        public uint QuotaPeakPagedPoolUsage;
        public uint QuotaPagedPoolUsage;
        public uint QuotaPeakNonPagedPoolUsage;
        public uint QuotaNonPagedPoolUsage;
        public uint PagefileUsage;
        public uint PeakPagefileUsage;
    }
    [StructLayout(LayoutKind.Sequential, Size = 40)]
    [DllImport("psapi.dll", SetLastError = true)]
    unsafe static extern bool GetProcessMemoryInfo(IntPtr* hProcess, out PROCESS_MEMORY_COUNTERS* Memcounters, int size);

这是实现原生pinvok代码的calss

(一开始我试图测试native vs managed / .net方法) 但在尝试使用pinvoke vs .net之前,我潜入海峡检查 pinvoke * unsafe vs .net

之间的表现

所以这部分仍处于安全模式&#34; 是否应该用astrics治疗?

static class Nat
    {
        public static class IO
        {
            public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
                GetProcessIoCounters(System.Diagnostics.Process.GetCurrentProcess().Handle, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }
        public static class Mem
        {
            public static Dictionary<string, uint> GetAllMem(Process procToRtrivMem)
            {

                PROCESS_MEMORY_COUNTERS MemCounters;
                Dictionary<string, uint> retCountMemDict = new Dictionary<string, uint>();
                GetProcessMemoryInfo(System.Diagnostics.Process.GetCurrentProcess().Handle, out MemCounters, Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS))); //MemCounters.cb);
                retCountMemDict.Add("cb", MemCounters.cb);
                retCountMemDict.Add("PageFaultCount", MemCounters.PageFaultCount);
                retCountMemDict.Add("PeakWorkingSetSize", MemCounters.PeakWorkingSetSize);
                retCountMemDict.Add("WorkingSetSize", MemCounters.WorkingSetSize);
                retCountMemDict.Add("QuotaPeakPagedPoolUsage", MemCounters.QuotaPeakPagedPoolUsage);
                retCountMemDict.Add("QuotaPagedPoolUsage", MemCounters.QuotaPagedPoolUsage);

                retCountMemDict.Add("QuotaPeakNonPagedPoolUsage", MemCounters.QuotaPeakNonPagedPoolUsage);
                retCountMemDict.Add("QuotaNonPagedPoolUsage", MemCounters.QuotaNonPagedPoolUsage);
                retCountMemDict.Add("PagefileUsage", MemCounters.PagefileUsage);
                retCountMemDict.Add("PeakPagefileUsage", MemCounters.PeakPagefileUsage);

                return retCountMemDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }

    }

对不起,但更新是我错过了部分: 编译器选项

compilerOptions="/unsafe" // <<-- you can add this to the compiler config line.

虽然还在。我的问题才开始,因为不仅有一个错误:

Unsafe code may only appear if compiling with /unsafe 

但到处都是错误!

第一个例如:

            public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();

            --->>   GetProcessIoCounters(System.Diagnostics.Process.GetCurrentProcess().Handle, out counters);


                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);

该错误是针对该行调用GetProcesIoCounters()

错误3参数1:无法转换为&#39; System.IntPtr&#39;到&#39; System.IntPtr *&#39; g:\ RobDevI5-Raid-0 \ Documents \ Visual Studio 2010 \ WebSites \ WebSite2 \ App_Code \ CsExtensions.cs 416 42 g:... \ WebSite2 \

UPDAT - 代码似乎有效但我无法验证它是否正确使用不安全

不安全的signeture

    [DllImport("psapi.dll", SetLastError = true)]
    unsafe static extern bool GetProcessMemoryInfo(IntPtr* hProcess, out PROCESS_MEMORY_COUNTERS Memcounters, int size);

代码与我的&#34;不安全&#34;

        public static class IO
        {
            public static unsafe Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
                IntPtr* Hw = (IntPtr*)System.Diagnostics.Process.GetCurrentProcess().Handle;
                GetProcessIoCounters(Hw, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }

4 个答案:

答案 0 :(得分:1)

我认为您的网络配置行缺少compilerOptions =“/ unsafe +”part

e.g。

        <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" compilerOptions="/unsafe+" warningLevel="4" />
    </compilers>

来自

答案 1 :(得分:1)

听起来您需要了解星号代表什么。在C#中,与其他类C语言一样,它表示指针类型。例如:

int *

...表示“指向int的指针”。也就是说,此变量的值表示包含int的内存位置。 C#和其他.NET语言实现了一种称为类型安全的东西,这意味着很难在内存中错误解释值(例如,尝试在实际包含int的内存位置读取字符串),这在广义上说是有用的事情。但是,有时候,当您与本机代码交互时,能够处理指针是很有用的。这颠覆了类型安全机制,因此您的代码必须标记为unsafe,并且您需要使用已经注明的/unsafe开关进行编译。

您似乎建议您在p / invoke和使用不安全代码之间做出决定。根据我的经验,这很少出现,因为存在两种技术来解决不同的问题。 P / invoke允许您以通常不需要使用不安全代码的方式与本机代码交互,但事实上它取决于您正在与之交互的本机代码的性质。

当您询问您的“安全模式”代码“是否也应该使用astrics进行处理?”我希望我的解释告诉您,您没有使用星号处理代码,但您可以根据需要逐个声明变量。

另外,GetProcessIoCounters的p / invoke声明看起来不对。您很少看到IntPtr *类型的参数。查看http://pinvoke.net以查找正确的声明。

要清除更多术语,可以管理或取消管理代码。始终管理C#代码。非托管代码将使用多种语言之一编写,例如C,C ++等.C#代码虽然总是被管理,但可以是类型安全的(默认)或者您可以将C#代码块标记为不安全,这允许您使用指针类型。

答案 2 :(得分:1)

好的,您需要更改一些内容,如下所示

using System.Collections.Generic;
using System.Runtime.InteropServices;
using System;
using System.Diagnostics;
static class Nat
{
    [StructLayout(LayoutKind.Sequential]
    struct IO_COUNTERS
    {
        public ulong ReadOperationCount;
        public ulong WriteOperationCount;
        public ulong OtherOperationCount;
        public ulong ReadTransferCount;
        public ulong WriteTransferCount;
        public ulong OtherTransferCount;
    }
    [DllImport("kernel32.dll")]
    unsafe static extern bool GetProcessIoCounters(IntPtr ProcessHandle, out IO_COUNTERS IoCounters);

    [StructLayout(LayoutKind.Sequential, Size = 40)]
    private struct PROCESS_MEMORY_COUNTERS
    {
        public uint cb;
        public uint PageFaultCount;
        public uint PeakWorkingSetSize;
        public uint WorkingSetSize;
        public uint QuotaPeakPagedPoolUsage;
        public uint QuotaPagedPoolUsage;
        public uint QuotaPeakNonPagedPoolUsage;
        public uint QuotaNonPagedPoolUsage;
        public uint PagefileUsage;
        public uint PeakPagefileUsage;
    }

    [DllImport("psapi.dll", SetLastError = true)]
    unsafe static extern bool GetProcessMemoryInfo(IntPtr* hProcess, out PROCESS_MEMORY_COUNTERS* Memcounters, int size);

    public static class IO
    {
        unsafe public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
        {
            IO_COUNTERS counters;
            Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
            IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

            GetProcessIoCounters(ptr, out counters);
            retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
            retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
            retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
            retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
            retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
            retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
            return retCountIoDict;
            //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
            //    " Mb of data.";

        }
    }
    public static class Mem
    {
        unsafe public static Dictionary<string, uint> GetAllMem(Process procToRtrivMem)
        {

            PROCESS_MEMORY_COUNTERS* MemCounters;
            Dictionary<string, uint> retCountMemDict = new Dictionary<string, uint>();
            IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

            GetProcessMemoryInfo(&ptr, out MemCounters, Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS))); //MemCounters.cb);
            retCountMemDict.Add("cb", MemCounters->cb);
            retCountMemDict.Add("PageFaultCount", MemCounters->PageFaultCount);
            retCountMemDict.Add("PeakWorkingSetSize", MemCounters->PeakWorkingSetSize);
            retCountMemDict.Add("WorkingSetSize", MemCounters->WorkingSetSize);
            retCountMemDict.Add("QuotaPeakPagedPoolUsage", MemCounters->QuotaPeakPagedPoolUsage);
            retCountMemDict.Add("QuotaPagedPoolUsage", MemCounters->QuotaPagedPoolUsage);

            retCountMemDict.Add("QuotaPeakNonPagedPoolUsage", MemCounters->QuotaPeakNonPagedPoolUsage);
            retCountMemDict.Add("QuotaNonPagedPoolUsage", MemCounters->QuotaNonPagedPoolUsage);
            retCountMemDict.Add("PagefileUsage", MemCounters->PagefileUsage);
            retCountMemDict.Add("PeakPagefileUsage", MemCounters->PeakPagefileUsage);

            return retCountMemDict;
            //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
            //    " Mb of data.";

        }
    }

}

答案 3 :(得分:1)

Necromancing。
接受的答案包含不起作用的代码。
以下是可以正常工作的更正版本:

namespace MemoryInfo
{


    class Program
    {

        static void Main(string[] args)
        {
            System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
            Nat.Mem.GetAllMem(proc);
            Nat.IO.GetALLIO(proc);
        }
    }



    // http://www.pinvoke.net/default.aspx/psapi.getprocessmemoryinfo
    static class Nat
    {


        // [DllImport("kernel32.dll")]
        // public static extern IntPtr GetCurrentProcess();

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        private struct IO_COUNTERS
        {
            public ulong ReadOperationCount;
            public ulong WriteOperationCount;
            public ulong OtherOperationCount;
            public ulong ReadTransferCount;
            public ulong WriteTransferCount;
            public ulong OtherTransferCount;
        }


        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Size = 40)]
        private struct PROCESS_MEMORY_COUNTERS
        {
            public uint cb; // The size of the structure, in bytes (DWORD).
            public uint PageFaultCount; // The number of page faults (DWORD).
            public uint PeakWorkingSetSize; // The peak working set size, in bytes (SIZE_T).
            public uint WorkingSetSize; // The current working set size, in bytes (SIZE_T).
            public uint QuotaPeakPagedPoolUsage; // The peak paged pool usage, in bytes (SIZE_T).
            public uint QuotaPagedPoolUsage; // The current paged pool usage, in bytes (SIZE_T).
            public uint QuotaPeakNonPagedPoolUsage; // The peak nonpaged pool usage, in bytes (SIZE_T).
            public uint QuotaNonPagedPoolUsage; // The current nonpaged pool usage, in bytes (SIZE_T).
            public uint PagefileUsage; // The Commit Charge value in bytes for this process (SIZE_T). Commit Charge is the total amount of memory that the memory manager has committed for a running process.
            public uint PeakPagefileUsage; // The peak value in bytes of the Commit Charge during the lifetime of this process (SIZE_T).
        }


        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private unsafe static extern bool GetProcessIoCounters(System.IntPtr ProcessHandle, out IO_COUNTERS IoCounters);

        [System.Runtime.InteropServices.DllImport("psapi.dll", SetLastError = true)]
        private unsafe static extern bool GetProcessMemoryInfo(System.IntPtr hProcess, out PROCESS_MEMORY_COUNTERS counters, uint size);


        public static class IO
        {
            unsafe public static System.Collections.Generic.Dictionary<string, ulong> GetALLIO(System.Diagnostics.Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                System.Collections.Generic.Dictionary<string, ulong> retCountIoDict = 
                    new System.Collections.Generic.Dictionary<string, ulong>();
                System.IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

                GetProcessIoCounters(ptr, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        } // End Class IO 


        public static class Mem
        {
            unsafe public static System.Collections.Generic.Dictionary<string, uint> GetAllMem(System.Diagnostics.Process procToRtrivMem)
            {
                PROCESS_MEMORY_COUNTERS MemCounters;
                System.Collections.Generic.Dictionary<string, uint> retCountMemDict = 
                    new System.Collections.Generic.Dictionary<string, uint>();
                System.IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;
                uint nativeStructSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS));


                GetProcessMemoryInfo(ptr, out MemCounters, nativeStructSize); //MemCounters.cb);
                retCountMemDict.Add("cb", MemCounters.cb);
                retCountMemDict.Add("PageFaultCount", MemCounters.PageFaultCount);
                retCountMemDict.Add("PeakWorkingSetSize", MemCounters.PeakWorkingSetSize);
                retCountMemDict.Add("WorkingSetSize", MemCounters.WorkingSetSize);
                retCountMemDict.Add("QuotaPeakPagedPoolUsage", MemCounters.QuotaPeakPagedPoolUsage);
                retCountMemDict.Add("QuotaPagedPoolUsage", MemCounters.QuotaPagedPoolUsage);

                retCountMemDict.Add("QuotaPeakNonPagedPoolUsage", MemCounters.QuotaPeakNonPagedPoolUsage);
                retCountMemDict.Add("QuotaNonPagedPoolUsage", MemCounters.QuotaNonPagedPoolUsage);
                retCountMemDict.Add("PagefileUsage", MemCounters.PagefileUsage);
                retCountMemDict.Add("PeakPagefileUsage", MemCounters.PeakPagefileUsage);

                return retCountMemDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";
            }


        } // End Class Mem

    }




}