none
net webform 程序错误! RRS feed

  • 问题

  • 尝试读取或写入受保护的内存。这通常知识其他内存已损坏。 说明:执行当前Web请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关错误以及代码中导致错误的处理的详细信息。 异常信息:System.AccessViolationException:尝试读取或写入受保护的内存。这通常知识其他内存已损坏。 ..........
    Netshao
    • 已移动 孟宪会Moderator 2009年10月29日 0:51 (发件人:.NET Framework 一般性问题讨论区)
    • 已移动 孟宪会Moderator 2009年10月29日 1:05 (发件人:ASP.NET 与 AJAX)
    2009年10月26日 8:53

答案

  • 你好!

    我看了一下你的源代码,是连Oracle数据库的吧。因为不是微软的产品,所以在本地我无法进一步调查。

    但是我猜测有可能是因为你的数据连接在多次调用之后并未关闭,所以导致内存占用过多而泄露。

    我建议你可以用Using关键字来处理一些数据连接的代码,例如OleDbConnection、OleDbDataReader:

    using (OleDbConnection connection = new OleDbConnection(connectionString))

     

    这样,如果在连接数据库过程中,报了一些异常的话,也会把连接关闭,而不是通过代码来关闭。通过代码的话,可能就会出现发生异常,而连接关闭的语句并未被执行。

    希望对你有所帮助。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.

    2009年10月28日 10:20
  • 如果你的数据很多,最好不要使用这样的方法

    DataSet ds = new DataSet();
    sda.Fill(ds);

    这样,你查询的数据会整个返回到内存中进行保存,如果使用人数多,势必会导致内存不足。

    同数据库打交道,最好的作法是只取必要的信息。

    另外,注意及时更新系统和数据库的最新补丁

    【孟子E章】
    2009年10月29日 1:05
    版主
  • OleDb只是一种通用的连接数据库的方法,性能不是很好。建议使用数据库专用的提供程序,
    如Sql Server使用SqlClient
    Oracle使用 Oracle Data Provider for .NET / ODP.NET或者 .NET Framework Data Provider for Oracle,


    MySql也有自己的为.NET制作的驱动

    【孟子E章】
    2009年10月30日 5:19
    版主
  • 看你的sql语句,,好像是蛮复杂的。你可以进行优化,或者采用多步查询的方法实现。

            string sql = "";
            sql = sql + "select a.contract_no,a.project_name_c,b.contract_sub_no,b.car_no,e.pcompany,d.username as SalesPerson,b.flag from";
            sql = sql + " (select t1.contract_no,t1.project_name_c,t1.contract_office,t1.sales_person from sddba.sdprj1 t1) a";
            sql = sql + ",(select t2.contract_no,t2.contract_sub_no,t2.car_no,t2.input_status,t2.flag_a||'-'||t2.flag_c||'-'||t2.flag_p as flag  from sddba.sdprj2 t2";
            sql = sql + " where t2.input_status='2' and (t2.flag_c='3' and (t2.flag_p='0' or t2.flag_p='1'))) b";
            sql = sql + ",(select t5.user_id,t5.last_name||t5.first_name as username,t5.dept from sydba.syuserms t5) d";
            sql = sql + ",(select t6.code,t6.description_c as pCompany from cmdba.cmcdms t6 where t6.code_item_no='001' and t6.data1='1') e";
            sql = sql + " where a.contract_no=b.contract_no and a.sales_person=d.user_id and a.contract_office=e.code and a.contract_no like '%" + pContract_No + "%'";
            sql = sql + " order by b.contract_no,b.input_status,b.contract_sub_no";

    很可能是sql语句不够优化导致的
     
    【孟子E章】
    2009年10月30日 5:25
    版主

全部回复

  • 一般是由于不具有权限而非法操作


    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://blog.tanging.net
    2009年10月26日 10:50
    版主
  • 你好!   

    如果非托管代码或不安全代码试图对尚未分配的或不具有访问权限的内存进行读操作或写操作,就会发生访问冲突。并非所有通过无效指针的读或写操作都会导致访问冲突,所以访问冲突通常指示已经通过无效指针进行多次读或写操作,并且内存内容可能已损坏。

    在托管代码中,所有的引用或者有效或者为空。试图在可验证代码中引用空引用的任何操作都将引发 NullReferenceException。

    根据平台不同,不安全的托管代码中发生的访问冲突可以表示为 NullReferenceExceptionAccessViolationException

    向上冒泡到托管代码的非托管代码中的访问冲突总是包装在 AccessViolationException 中。


    周雪峰
    2009年10月26日 16:24
    版主
  • 非常感谢二位版主的回复!

    咱们这个论坛好像不能上传图片和附件吧?

    我的这问题非常急!

    希望二位版主能帮我看看!能留下QQ吗?

    先谢谢了!


    Netshao
    • 已标记为答案 Netshao 2009年10月28日 5:30
    • 取消答案标记 Netshao 2009年10月28日 5:31
    2009年10月28日 5:28
  • 你可以贴图啊。打开"HTML"编辑器,写<img src="[URL]">。

    或者最简单的,你上传你的图片,然后把链接贴到这里来。
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年10月28日 5:31
  • 谢谢版主回复!

    我的程序部署后,可以正常访问!但访问次数过多后!就偶尔出现这个错误。

    一般我重启一下如下服务:

    World Wide Web Publishing

    就OK了!

    错误图片如下:
     

    代码下载:
    http://shao.yoyotao.net/upload/HSWEB1.part01.rar
    http://shao.yoyotao.net/upload/HSWEB1.part02.rar
    http://shao.yoyotao.net/upload/HSWEB1.part03.rar

    不知道为什么?急盼答复!

    谢谢!


    Netshao
    2009年10月28日 8:44
  • 你好!

    我看了一下你的源代码,是连Oracle数据库的吧。因为不是微软的产品,所以在本地我无法进一步调查。

    但是我猜测有可能是因为你的数据连接在多次调用之后并未关闭,所以导致内存占用过多而泄露。

    我建议你可以用Using关键字来处理一些数据连接的代码,例如OleDbConnection、OleDbDataReader:

    using (OleDbConnection connection = new OleDbConnection(connectionString))

     

    这样,如果在连接数据库过程中,报了一些异常的话,也会把连接关闭,而不是通过代码来关闭。通过代码的话,可能就会出现发生异常,而连接关闭的语句并未被执行。

    希望对你有所帮助。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.

    2009年10月28日 10:20
  • 感谢版主的回复!

    我回头全部改为using试一下!

    我还有以下几个问题请教一下:
    1.using (OleDbConnection con = DB.createConnection())
            {
                //OleDbConnection con = DB.createConnection();
                OleDbDataAdapter sda = new OleDbDataAdapter();
                string sql = "";
                sql = sql + "select d.contract_sub_no,d.c_group,t.project_name_c,d.car_no,cm.pcompany,d.delivery,d.remarks_c";
                sql = sql + " from sddba.sdprj1 t,sddba.sdprj2 d,";
                sql = sql + "(select t.code,t.description_c as pcompany,mm.pSaleArea,t.data6 from cmdba.cmcdms t,";
                sql = sql + "(select tt.code,tt.description_c as pSaleArea from cmdba.cmcdms tt";
                sql = sql + " where tt.code_item_no='001') mm";
                sql = sql + " where t.code_item_no='001' and t.data1='1' and  t.data6=mm.code) cm";
                sql = sql + " where t.contract_no=d.contract_no ";
                sql = sql + " and t.contract_office=cm.code";
                sql = sql + " and t.contract_no='" + pContract_No + "'";
                sql = sql + " and cm.data6='" + pDept + "'";
                sda.SelectCommand = new OleDbCommand(sql, con);
                DataSet ds = new DataSet();
                sda.Fill(ds);
                ds.Dispose();
                //  con.Close();
                return ds.Tables[0];
            }

    使用OleDbDataAdapter时,应该不用con.open();吧?

    2.
    public static bool Update_SpecApproveCom(string pUser_id, string pApp_date_com, string pContract_No,string pContract_Sub_No)
        {
            try
            {
                string strFlag_C = "";
                OleDbConnection con = DB.createConnection();
                con.Open();
                string sql1 = "";
                sql1 = sql1 + "select t.flag_c from sddba.sdprj2 t where t.contract_no='" + pContract_No + "' and t.contract_sub_no='"+pContract_Sub_No+"'";
                OleDbCommand cmd1 = new OleDbCommand(sql1, con);
                OleDbDataReader dr = cmd1.ExecuteReader();
                while (dr.Read())
                {
                    strFlag_C = dr["flag_c"].ToString();
                }
                dr.Close();
                if (strFlag_C == "0")
                {
                    string sql2 = "";
                    sql2 = sql2 + "update sddba.sdprj2 t set t.flag_a='3',t.app_person_com='" + pUser_id + "',t.app_date_com='" + pApp_date_com + "'";
                    sql2 = sql2 + " where t.contract_no='" + pContract_No + "' and t.contract_sub_no='" + pContract_Sub_No + "'";
                    OleDbCommand cmd2 = new OleDbCommand(sql2, con);
                    cmd2.ExecuteNonQuery();
                }
                if (strFlag_C == "2")
                {
                    string sql3 = "";
                    sql3 = sql3 + "update sddba.sdprj2 t set t.flag_a='3',t.flag_c='1',t.app_person_com='" + pUser_id + "',t.app_date_com='" + pApp_date_com + "'";
                    sql3 = sql3 + " where t.contract_no='" + pContract_No + "' and t.contract_sub_no='" + pContract_Sub_No + "'";
                    OleDbCommand cmd3 = new OleDbCommand(sql3, con);
                    cmd3.ExecuteNonQuery();
                }
                con.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }

      这个过程中如果捕获到异常的话,连接会自动关闭吗?还是在catch过程中再增加一句 con.close();
     还有就是try语句是不是不用太靠前,放在dr.close()后即可。如果是这样的话,catch过程中是不是必须增加一句 con.close()?

    3.我自己编得的很多函数返回的是datatable.是不是返回的datatable多了。占用的内存就多啊?需要清一下吗?

    public static DataTable selectSDSPECApprovePCD(string pContract_No)
        {
            OleDbConnection con = DB.createConnection();
            con.Open();
            OleDbDataAdapter sda = new OleDbDataAdapter();
            string sql = "";
            sql = sql + "select a.contract_no,a.project_name_c,b.contract_sub_no,b.car_no,e.pcompany,d.username as SalesPerson,b.flag from";
            sql = sql + " (select t1.contract_no,t1.project_name_c,t1.contract_office,t1.sales_person from sddba.sdprj1 t1) a";
            sql = sql + ",(select t2.contract_no,t2.contract_sub_no,t2.car_no,t2.input_status,t2.flag_a||'-'||t2.flag_c||'-'||t2.flag_p as flag  from sddba.sdprj2 t2";
            sql = sql + " where t2.input_status='2' and (t2.flag_c='3' and (t2.flag_p='0' or t2.flag_p='1'))) b";
            sql = sql + ",(select t5.user_id,t5.last_name||t5.first_name as username,t5.dept from sydba.syuserms t5) d";
            sql = sql + ",(select t6.code,t6.description_c as pCompany from cmdba.cmcdms t6 where t6.code_item_no='001' and t6.data1='1') e";
            sql = sql + " where a.contract_no=b.contract_no and a.sales_person=d.user_id and a.contract_office=e.code and a.contract_no like '%" + pContract_No + "%'";
            sql = sql + " order by b.contract_no,b.input_status,b.contract_sub_no";
            sda.SelectCommand = new OleDbCommand(sql, con);
            DataSet ds = new DataSet();
            sda.Fill(ds, "ApprovePCD");
            ds.Dispose();
            con.Close();
            return ds.Tables["ApprovePCD"];
        }

     我在代码中追加了一句ds.Dispose();这个是这么用吗?

    4.这个问题让我郁闷了好久!找了很多资料也没解决!我不知道标准的多用户访问程序,连接的语法应该如何写!
      我看看很多视频,有的用using的方式,有的建议手写!其中微软邵志东老师的视频很多就用的是手动打开关闭连接的方式。我的程序基本是按照他的语法结构写的,我想应该没问题啊!可不知道为什么就是在多用户多次访问后就报错!重启:
    World Wide Web Publishing 服务就好了。
    希望版主能帮我看看我的源码关于连接部分逻辑对不对!我的程序11月初就要求正式用了!

    5.如果可以的话,QQ远程协助一下吧!
     

    以上

    谢谢!急盼回复!


    Netshao
    • 已编辑 Netshao 2009年10月29日 1:17
    2009年10月29日 0:48
  • 如果你的数据很多,最好不要使用这样的方法

    DataSet ds = new DataSet();
    sda.Fill(ds);

    这样,你查询的数据会整个返回到内存中进行保存,如果使用人数多,势必会导致内存不足。

    同数据库打交道,最好的作法是只取必要的信息。

    另外,注意及时更新系统和数据库的最新补丁

    【孟子E章】
    2009年10月29日 1:05
    版主
  • 我的DataTable数据量最大大概是300记录,20个字段吧!

    要向DataGrid绑定,不用datatable话,有其他的方法吗?

    sql = sql + " order by b.contract_no,b.input_status,b.contract_sub_no";
            sda.SelectCommand = new OleDbCommand(sql, con);
            DataSet ds = new DataSet();
            sda.Fill(ds, "ApprovePCD");
            ds.Dispose();
            con.Close();

    这个语句(ds.Dispose();)用过吗?管用吗?据说可以释放内存!

    另外,
    程序在出现内存错误后,如果不重启服务的话。再访问程序的登录界面都进不去。显示的结果一般如下:


    Netshao
    2009年10月29日 1:24
  • OleDb只是一种通用的连接数据库的方法,性能不是很好。建议使用数据库专用的提供程序,
    如Sql Server使用SqlClient
    Oracle使用 Oracle Data Provider for .NET / ODP.NET或者 .NET Framework Data Provider for Oracle,


    MySql也有自己的为.NET制作的驱动

    【孟子E章】
    2009年10月30日 5:19
    版主
  • 看你的sql语句,,好像是蛮复杂的。你可以进行优化,或者采用多步查询的方法实现。

            string sql = "";
            sql = sql + "select a.contract_no,a.project_name_c,b.contract_sub_no,b.car_no,e.pcompany,d.username as SalesPerson,b.flag from";
            sql = sql + " (select t1.contract_no,t1.project_name_c,t1.contract_office,t1.sales_person from sddba.sdprj1 t1) a";
            sql = sql + ",(select t2.contract_no,t2.contract_sub_no,t2.car_no,t2.input_status,t2.flag_a||'-'||t2.flag_c||'-'||t2.flag_p as flag  from sddba.sdprj2 t2";
            sql = sql + " where t2.input_status='2' and (t2.flag_c='3' and (t2.flag_p='0' or t2.flag_p='1'))) b";
            sql = sql + ",(select t5.user_id,t5.last_name||t5.first_name as username,t5.dept from sydba.syuserms t5) d";
            sql = sql + ",(select t6.code,t6.description_c as pCompany from cmdba.cmcdms t6 where t6.code_item_no='001' and t6.data1='1') e";
            sql = sql + " where a.contract_no=b.contract_no and a.sales_person=d.user_id and a.contract_office=e.code and a.contract_no like '%" + pContract_No + "%'";
            sql = sql + " order by b.contract_no,b.input_status,b.contract_sub_no";

    很可能是sql语句不够优化导致的
     
    【孟子E章】
    2009年10月30日 5:25
    版主
  • 我同意孟版主的意见,SQL的语句要尽量清晰,不宜太过复杂。另外就是我之前提到的数据库连接的问题,因为造成错误的原因可能有好几种了,所以只能尽量一一排除。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年10月30日 5:59
  • 谢谢孟版主的回复!
    1.net 数据库连接问题
    你说的是使用:System.Data.OracleClient;吗?
    我的Oracle 是8.16。我查了一下,这本版本只能用System.Data.OleDb;
    2.Sql 优化问题
    我的sql是多个表连接,查出符合条件的记录。同时,与字典表关联读取代码的描述信息。
    应该没问题吧?如果分步,如何返回给DataGrid啊?

    Netshao
    2009年11月2日 1:10
  • 版主问题还没解决啊?请求帮助!
    Netshao
    • 已建议为答案 simon tang 2010年2月21日 10:44
    2009年11月9日 6:23
  • 我也遇到同样的问题,找到答案,麻烦回复我一份:wz96@galanz.com.cn

    2010年2月21日 10:44