C# 如何从自定义成员资格提供程序中处置自定义对象

C# 如何从自定义成员资格提供程序中处置自定义对象,c#,asp.net,visual-studio-2005,membership-provider,C#,Asp.net,Visual Studio 2005,Membership Provider,我已经创建了我的自定义会员资格提供商。我在这个提供程序中使用了DBConnect类的一个实例来处理数据库函数。请看下面的代码: public class SGIMembershipProvider : MembershipProvider { #region "[ Property Variables ]" private int newPasswordLength = 8; private string connectionString; private str

我已经创建了我的自定义会员资格提供商。我在这个提供程序中使用了DBConnect类的一个实例来处理数据库函数。请看下面的代码:

public class SGIMembershipProvider : MembershipProvider
{
    #region "[ Property Variables ]"
    private int newPasswordLength = 8;
    private string connectionString;
    private string applicationName;
    private bool enablePasswordReset;
    private bool enablePasswordRetrieval;
    private bool requiresQuestionAndAnswer;
    private bool requiresUniqueEmail;
    private int maxInvalidPasswordAttempts;
    private int passwordAttemptWindow;
    private MembershipPasswordFormat passwordFormat;
    private int minRequiredNonAlphanumericCharacters;
    private int minRequiredPasswordLength;
    private string passwordStrengthRegularExpression;
    private MachineKeySection machineKey; 

    **private DBConnect dbConn;**
    #endregion

.......

    public override bool ChangePassword(string username, string oldPassword, string newPassword)
    {
        if (!ValidateUser(username, oldPassword))
            return false;

        ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true);

        OnValidatingPassword(args);

        if (args.Cancel)
        {
            if (args.FailureInformation != null)
            {
                throw args.FailureInformation;
            }
            else
            {
                throw new Exception("Change password canceled due to new password validation failure.");
            }
        }
        SqlParameter[] p = new SqlParameter[3];
        p[0] = new SqlParameter("@applicationName", applicationName);
        p[1] = new SqlParameter("@username", username);
        p[2] = new SqlParameter("@password", EncodePassword(newPassword));

        bool retval = **dbConn.ExecuteSP("User_ChangePassword", p);**
        return retval;
    } //ChangePassword


    public override void Initialize(string name, NameValueCollection config)
    {
        if (config == null)
        {
            throw new ArgumentNullException("config");
        }

        ......

        ConnectionStringSettings ConnectionStringSettings = ConfigurationManager.ConnectionStrings[config["connectionStringName"]];

        if ((ConnectionStringSettings == null) || (ConnectionStringSettings.ConnectionString.Trim() == String.Empty))
        {
            throw new ProviderException("Connection string cannot be blank.");
        }

        connectionString = ConnectionStringSettings.ConnectionString;

        **dbConn = new DBConnect(connectionString);
        dbConn.ConnectToDB();**

        ......

} //Initialize

......

} // SGIMembershipProvider 
我在
Initialize()
事件中实例化了
dbConn
对象

我的问题是,当
SGIMembershipProvider
的对象被处理掉时,如何处理掉这个对象

我知道GC会为我完成这一切,但我需要显式地处理该对象。甚至我也尝试重写
Finalize()
,但没有这样的可重写方法。我还尝试为
SGIMembershipProvider
创建析构函数


有人能给我提供解决方案吗。

据我所知,它不可
IDisposable
(也不可),所以我们这里真正谈论的是垃圾收集,而不是处理。您应该能够添加自己的终结器(
~SGIMembershipProvider(){}
),但该终结器应该只与非托管对象对话-毕竟,其他托管对象也将被收集(并且应该处理它们自己的非托管对象,如果有的话,这是罕见的)。

对于此特定场景,我建议直接在您需要的每个方法中创建DB连接,而不是存储对它的引用。将它包装在using语句中,让框架为您处理它

我推荐这种方法的原因是,您不会因为挂起连接对象而节省任何资源。连接池将为您处理现有打开连接的重用。连接池在非托管代码级别工作。当您关闭/处置托管连接对象时,它不一定关闭物理非托管连接,它只是将连接返回到连接池。然后,控制池的非托管代码将决定如何处理它(关闭它,保持它打开一段时间,将它提供给另一个需要它的进程)。同样,当您创建托管连接时,不一定是从头开始创建新连接,您可能只是在重用现有连接


我确实认为框架需要使这个对象成为一次性的。我可以想到很多其他情况,在这些情况下,我希望重用提供者中的某些内容,并最终将其处理。

谢谢Marc!正如我所说,我还创建了自己的终结器~SGIMembershipProvider(){}。这会被处决吗?@IrfanRaza-是的;当它被垃圾收集时。如果它没有被调用,那么引擎可能会在整个过程中保留一个提供程序。还有其他更好的方法吗?