You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在WCF方法返回DataSet时,using语句的资源释放方式是否恰当?

在WCF中返回DataSet时的资源释放方式对比分析

问题描述

在WCF方法中返回DataSet时,第一种使用using语句处理SqlConnection、SqlCommand、SqlDataAdapter的资源释放方式是否合适?还是必须采用第二种实现方式?


第一种实现代码

public DataSet SearchName(string LastName, string FirstName, DateTime DateOfBirth)
{
    try {
        using (SqlConnection con = new SqlConnection(Properties.Settings.Default.DBPreTrial))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = "spSearchName";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = con;
                cmd.Parameters.AddWithValue("@LastName", LastName);
                cmd.Parameters.AddWithValue("@FirstName", FirstName);
                cmd.Parameters.AddWithValue("@DateOfBirth", DateOfBirth);

                using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    DataSet dtDocData = new DataSet();
                    da.Fill(dtDocData);

                    return dtDocData;
                }
            }
        }
    }
    catch (Exception ex)
    {
        throw new FaultException("Exception - SearchName: " + LastName + ", " + FirstName + ", " + Convert.ToString(DateOfBirth) + " : " + ex.Message);
    }
}

第二种实现代码

public DataSet SearchName(string LastName, string FirstName, DateTime DateOfBirth)
{
    DataSet dtDocData = new DataSet();

    try {
        using (SqlConnection con = new SqlConnection(Properties.Settings.Default.DBPreTrial))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = "spSearchName";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = con;
                cmd.Parameters.AddWithValue("@LastName", LastName);
                cmd.Parameters.AddWithValue("@FirstName", FirstName);
                cmd.Parameters.AddWithValue("@DateOfBirth", DateOfBirth);

                using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    da.Fill(dtDocData);

                }
            }
        }

        return dtDocData;
    }
    catch (Exception ex)
    {
        throw new FaultException("Exception - SearchName: " + LastName + ", " + FirstName + ", " + Convert.ToString(DateOfBirth) + " : " + ex.Message);
    }
    if (dtDocData != null)
    {
        dtDocData.Dispose();
    }
}

分析结论

  • 第一种实现是完全合适且推荐的

    • SqlConnection、SqlCommand、SqlDataAdapter都实现了IDisposable接口,using语句能确保这些对象在代码块结束时自动调用Dispose(),及时释放数据库连接等非托管资源,从根源避免资源泄漏问题。
    • DataSet是在SqlDataAdapter的using块内创建并填充,填充完成后直接返回。这里不用担心DataSet被提前释放:DataSet属于纯托管对象,虽然它实现了IDisposable接口,但内部没有需要手动清理的非托管资源;而且返回后调用方会持有该对象的引用,不会被GC随意回收。
    • 代码结构紧凑,逻辑清晰,没有冗余代码。
  • 第二种实现存在冗余问题,不推荐

    • 方法末尾的if (dtDocData != null) { dtDocData.Dispose(); }代码永远不会执行:try块要么正常返回dtDocData,要么catch块抛出异常直接跳出方法,程序流程根本走不到这段代码。
    • DataSet提前在方法开头创建属于不必要的操作,反而分散了代码逻辑。
    • 虽然它也用using处理了数据库相关对象,但后续的冗余代码属于画蛇添足,没有任何实际作用。

总结:第一种实现是正确的资源释放方式,完全满足WCF场景下的需求,不需要采用第二种方式。

内容的提问来源于stack exchange,提问作者Bill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:58:20