Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9487978
  • 博文数量: 1227
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 20273
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-16 12:40
文章分类

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-04-02 14:56:52

下载本文示例代码
我创建了一个 Web 应用程序,它的界面功能十分丰富。这个程序主要是由 XML、XSLT 和 JScript 构建的。我遇到了一个大问题就是它消耗了大量的内存,但我不知道为何会出现这种情况。我使用 闭合函数(closures:一种在函数中定义函数的方法)来实现事件处理,我怀疑就是使用它才导致的内存泄露。

用闭合函数作为事件处理的实现,是导致内存泄露的普遍原因。闭合函数总是允许内部函数访问外部函数的参数和变量。
  Eric Lippert 的 Blog (译者:Web Log 的简称)上有一篇关于闭合函数和内存泄露的文章:What are closures?。然而请注意,在这篇文章截稿前仍旧有一个错误没有改正。当微软IE浏览器导航到某一页时 ,循环引用会使效率下降的说法并不正确。几年前当这个问题第一次出现时,并没有造成很大影响,但是IE团队发现它影响很多现存的页面,所以还是关闭了此项功能 。
  创建一个界面功能丰富的 Web 应用程序,就像你前面所叙述的。首先这不是一个好想法,它会导致软件过于臃肿以至于泄漏内存。这方面内容请参见:Thin To My Chagrin
  根据函数是否被动态地创建来谨慎地使用闭合函数语义。如果函数是被动态地创建,例如通过 new 操作符来声明,那么你应该寻找一种方法来避免这么做。使用New表达式生成的函数相当于使用Eval表达式,而Eval表达式会影响性能。它会执行编译过程。如果这个函数需要被动态地创建,并且可以不需要使用闭合函数语 义,那么将发生器放到一个辅助函数中,该辅助函数没有那些会形成循环引用的参数。这样,所产生的函数将会在一些不需要回指向IE对象模型的事件前结束。如果这个函数是静态创建的,不需要使用闭合函数语 义,就不要将它嵌入到其它函数中。并且重构你的应用程序直到你脱离这种困境。

我怎样才能确定 XmlDataDocument与 DataSet 是关联的?如果我采用下面的代码来从 DataSet 中创建一个XmlDataDocument: 便很容易获得与这个 XmlDataDocument 相一致的 DataSet,如下所示:
DataSet dataset = xmlData.DataSet;
  然而,一旦XmlDataDocument与DataSet的关联关系建立起来,我怎样才能确定这个XmlDataDocument确实来自于DataSet呢?这很重要,因为如果我试图为DataSet创建第二个XmlDataDocument时,会抛出一个异常。 我依赖于DataSet。在许多方法中, 我以XML的格式来操作数据. 当DataSet在方法间被传递时,XmlDataDocumnet是否被创建了,它的引用是什么,我需要知道调用这些方法时其内部操作的相关知识。

没有简单的方法。很不幸,DataSet不提供任何公有的API来检查一个 XmlDataDocument 是否与之相关或者提供它的一个引用。 然而,作为一个折中的办法,你可以选择以下两条之一来解决:
  1. 总是在一个Try-Catch块中实例化 XmlDataDocument,并且捕获异常变量,如果DataSet已经与一个 XmlDataDocument 相关联,那么就会抛出异常。
  2. 利用程序跟踪判断 DataSet 实例是否已经与一个 XmlDataDocument 相关联。

  之后你可以使用 DataSet.ExtendedProperty 创建一个用户自定义属性来保持对一个不知道是否被关联的 XmlDataDocument 的跟踪。
  例如,使用如下代码来注册一个关联操作:

DataSet.ExtendedProperty.Add("XmlDataDocumentAttached", "1")

  这个扩展属性将会在实例化XmlDataDocument之前被检查。

  如果你可以确定不会通过Web服务或远程调用来序列华化 DataSet, 那么你就可以注册这个与之关联的 XmlDataDocument 实例作为 DataSet 的属性值(如果一个对象作为 DataSet 的扩展属性,那么它的序列化会被中断)。

我有一个运行了两年的Web应用程序,他有一个所有页面都要使用的标题菜单。它是按照下面的方式被ASP页面调用的:

#include file="../Include/UDBMenuAccess.asp"

  我现在为这个站点添加了两个新的.aspx页面,并且我想要包含这个菜单。可是,我的新页面不是认不出包含的这个菜单就是产生很多错误。难道无法将一个asp页面包含在一个 aspx 页面中么?有解决办法么? 

将这个旧的包含文件转换为一个 .ascx 文件,之后将其放入你的 aspx 页面。包含页并没有失效,他们现在被更简单地称作自定义控件并且更加强大。记住,编写这些控件与编写工程所使用的语言必须相同。 如果你决定采用C#,并且你有一些采用VisualBasic 编写的包含页面,那么你需要将他们转换为C#。请看下面这个例子,如 Figure 1。 现在,你可以使用如下方法将它包含在aspx页面中了。在aspx页面的顶部声明它。 

<%@ Register TagPrefix="thisSite" TagName="copyright"
 src="includes/cr.ascx" %>

之后,当你想在页面中放置它时,使用如下元素来调用它:



我有一段代码,如下:

SqlConnection sqlConnection;
CloseConnection()
{
    sqlConnection.Close();
    sqlConnection.Dispose();
    sqlConnection = null; 
}

  调用SqlConnection的Dispose方法是否可以将其从连接池中移除呢?还是要同时调用Dispose和Close方法呢? 我正在使用.NET Framework 1.1。我读了一片文章,上面说在.NET Framework 1.0中调用Dispose方法可以从连接池中移除连接,然而在.NET Framework 1.1却不行,是这样么?

Dispose方法不会从连接池中移除连接,它会将连接放回池中,如果以前没有这么做的话。对于.NET Framework  1.0 和 1.1, 你可以基本认为Close 与 Dispose是同等的。作为你的问题的回答, Dispose 在.NET Framework  1.0 和 1.1中是相同的。总是调用Close或Dispose方法来释放一个SqlConnection 可以使你避免许多基于垃圾回收和清除方面的问题。如果你想处理的更好,你可以像下面所展示的代码那样使用Using关键字:

using ( SqlConnection conn = new SqlConnection(CONNECT_STRING) )
{
    try
    {
        conn.Open();
        // Use conn in here...
    }
    catch ( SqlException sqlEX )
    {
        // Log errors here...
    }
} //一旦超出这个括号的范围SqlConnection对象的Dispose方法会被调用


  更多关于SqlConnection的编程实例,请参见 .

是否有从XSD文件中获取XML schema 命名空间URI信息的内置方法呢?还是需要我手动的去分析这个schema文件呢?我想让用户选择一批XSD文件,并自动载入它们的schema命名空间URI。而不用要求他们输入过多的信息。

你有至少三种选择来解决你的问题。第一,你可以将schema装载入一个DOM,并使用XPath来选择/xs:schema/@targetNamespace结点(xs对应于)。 第二,你可以将schema装载入一个schema对象模型(SOM),通过调用System.Xml.Schema.XmlSchema.Read方法并读取 argetNamespace属性来实现。最后一个选择是使用 XmlTextReader来分析schema中的第一个元素,检查{},并读取 targetNamespace属性。
  这些方法实现起来都十分简单。然而,最后一个是到目前为止最高效的,无论从空间利用率还是从时间利用率来说,因为前两个方法都需要运行第三个方法,增加了额外的负担。

System.Data.SqlClient是怎么在批量的SQL语句中处理分号分隔符的?批处理看起来工作的很好,可是,在.NET Framework文档中我没有看到任何一篇关于分号的文档。
 下面的代码段

DECLARE @val int
SET @val=10

UPDATE dbo.Foo
SET val=@val
IF (@@ERROR <> 0) GOTO EXIT_SCRIPT

SET @val=20
UPDATE b
SET b.val=@val
FROM dbo.Foo AS f INNER JOIN dbo.Bar AS b ON f.id = b.id

IF (@@ERROR <> 0) GOTO EXIT_SCRIPT

EXIT_SCRIPT:

会与这段代码处理的不同么?

DECLARE @val int;SET @val=10;UPDATE dbo.Foo SET val=@val;IF (@@ERROR <> 0)
GOTO EXIT_SCRIPT;SET @val=20;UPDATE b SET b.val=@val FROM dbo.Foo AS f
INNER JOIN dbo.Bar AS b ON f.id = b.id;IF (@@ERROR <> 0)
GOTO EXIT_SCRIPT;EXIT_SCRIPT:;

在这种批处理中(例如事务处理,存储过程)调用的语句会产生什么不同的结果么?

SqlClient将所有的语句直接传给SQL Server,在客户端不加任何修改。SQL Server 将分号作为合法的分隔符,所以可以正常工作。就SQL Server而言,这两种批处理没有什么不同的。

我有一个关于ADO.NET中表间关系和已删除记录的问题。当我这么做时:

parentRow.GetChildRows( "relationship name" ) ;

我无法获得被标记为Deleted的返回记录。
  可是,我确实需要这些信息。我需要获取那些新增,修改或删除的相关记录。GetChildRows仅仅返回新增和修改的记录,但是不返回被删除的记录。
  我试图通过传递可选参数DataRowVersion

parentRow.GetChildRows("relationship name", DataRowVersion.Original);

使其返回那些删除的记录,但是并没有成功。我该怎么做呢?

GetChildRows的第二个参数控制你获取的数据的版本,你可以获取(current, original, or proposed)中的一种。 他不是记录属性(added, modified, deleted, unchanged)的过滤器 。
  要访问那些存在不确定改变属性的记录,你可以使用DataTable。在Select语句中创建一个寻找确定记录的过滤器(例如,FKColumn = Value),并提供记录属性(例如 Added,ModifiedCurrent, Deleted)。在  Figure 2 种有一些样例代码。
  如果你不介意使用数据视图,你也可以使用它。创建子视图并设置相应的记录属性过滤器,代码如下:

DataView vueCustomers = ds.Tables["Customers"].DefaultView;
    vueCustomers.Sort = "CustomerID";
DataView vuePendingOrders = 
    vueCustomers[vueCustomers.Find("ALFKI")].CreateChildView
    ("Customers_Orders");
vuePendingOrders.RowStateFilter = DesiredRowStates;
Console.WriteLine("ALFKI has {0} pending modified orders", 
    vuePendingOrders.Count);

如果你有问题或解答,请将其发送到: 。


致谢以下微软开发者提供的专家解答:Jeff Abrams, Kawarjit Bedi, Jeffrey Brendecke, Lale Divringi, Blaine Dockter, Yves Dolce, Tim Ewald, Michael Hestness, Eric Lippert, Matt Neerincx, Carl Nolan, Thomas Rahm, David Sceppa, Larry Sun,Vinayak Tadas。

 一个自定义控件
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="cr.ascx.cs" 
Inherits="thisSite.includes.cr_B" 
TargetSchema=""%>

?thisSite 2003 - Home - Contacts - Disclaimer

获取改变的记录
string strConn = "Data Source=(local);Initial 
Catalog=Northwind;Trusted_Connection=Yes;";
string strSQL = "SELECT CustomerID, CompanyName, ContactName FROM 
Customers WHERE CustomerID LIKE ''A%'';" +
"SELECT OrderID, CustomerID, OrderDate FROM Orders WHERE CustomerID LIKE ''A%''";
SqlDataAdapter da = new SqlDataAdapter(strSQL, strConn);
da.TableMappings.Add("Table", "Customers");
da.TableMappings.Add("Table1", "Orders");
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
DataSet ds = new DataSet();
da.Fill(ds);
ds.Relations.Add("Customers_Orders", 
                 ds.Tables["Customers"].Columns["CustomerID"], 
                 ds.Tables["Orders"].Columns["CustomerID"]);
 
DataRow row = ds.Tables["Customers"].Rows.Find("ALFKI");
DataRow[] ChildRows = row.GetChildRows("Customers_Orders");
Console.WriteLine("ALFKI has {0} orders", ChildRows.Length);
 
ChildRows[2].Delete();
ChildRows[4].Delete();
ChildRows[3]["OrderDate"] = DateTime.Today;
ds.Tables["Orders"].LoadDataRow(new Object[]{-1, "ALFKI", DateTime.Today}, 
    false);
 
DataViewRowState DesiredRowStates = DataViewRowState.Added | 
DataViewRowState.ModifiedCurrent | DataViewRowState.Deleted;
DataRow[] ChildPendingChanges = ds.Tables["Orders"].Select("CustomerID = 
    ''ALFKI''", "", DesiredRowStates);
Console.WriteLine("ALFKI has {0} pending modified orders", 
    ChildPendingChanges.Length);
下载本文示例代码
阅读(1121) | 评论(0) | 转发(0) |
0

上一篇:介绍两个 XML 文件操作类

下一篇:XML 文件

给主人留下些什么吧!~~