【问题标题】:How to Force Disposal of Objects / GC如何强制处理对象/GC
【发布时间】:2012-01-09 02:28:22
【问题描述】:

如何强制对象在使用后进行处理以释放内存?还有,你如何强制GC收集?

这是我的保存代码。我注意到,每次执行此功能时,我的内存消耗都会增加,最终会在几次点击后导致内存不足错误。

protected void btnSaveEmptyOC_Click(object sender, EventArgs e)
{


    try
    {

        if (ViewState["ServiceDetailID"].ToString() != null)
        {
            CashExpense tblCashExpenses = new CashExpense();
            Guid CashExpensesID = Guid.NewGuid();

            tblCashExpenses.CashExpensesID = CashExpensesID;


            tblCashExpenses.ServiceDetailsID = new Guid(ViewState["ServiceDetailID"].ToString());

            tblCashExpenses.Description = txtDescriptionEmptyOC.Text;
            tblCashExpenses.Quantity = Decimal.Parse(txtQTYEmptyOC.Text);
            tblCashExpenses.UnitCost = Decimal.Parse(txtUnitCostEmptyOC.Text);
            tblCashExpenses.CreatedBy = User.Identity.Name;
            tblCashExpenses.DateCreated = DateTime.Now;
            tblCashExpenses.CashExpensesTypeID = "OTHER";

            CashExpenses_worker.insert(tblCashExpenses);
            CashExpenses_worker.submit();
            //Clear items after saving
            txtDescriptionEmptyOC.Text = "";
            txtQTYEmptyOC.Text = "";
            txtUnitCostEmptyOC.Text = "";


            ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.InsertOC2, "SaveEmptyOC", this.Page);
            MyAuditProvider.Insert(this.GetType().ToString(), ViewState["MarginAnalysisID"].ToString(), MessageCenter.Mode.ADD, MessageCenter.CashExpenseMaintenace.InsertOC2, Page.Request, User);
            divOtherCost.Visible = false;
            grd_othercost.Visible = true;
            btnaddothercost.Visible = true;

            tblCashExpenses = null;
        }
        else
        {
            ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.SaveServiceDetailOC, "SaveEmptyOC", this.Page);
        }
    }
    catch
    {
        ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.InsertOCError, "SaveEmptyOC", this.Page);
    }

    finally
    {
        //Rebinds the Grid
        populategrd_othercost();
        Dispose();
        GC.SuppressFinalize(this);
    }
}

这是我的业务层类

public class CashExpensesBL
{
    CEADataStoreDataContext CashExpensesDB = new CEADataStoreDataContext();

    public IEnumerable<CashExpense> get()
    {
        return CashExpensesDB.CashExpenses;
    }
    public IEnumerable<CashExpense> get(Expression<Func<CashExpense, Boolean>> express)
    {
        return CashExpensesDB.CashExpenses.Where(express);
    }
    public void insert(CashExpense item)
    {
        CashExpensesDB.CashExpenses.InsertOnSubmit(item);
    }
    public void delete(CashExpense item)
    {
        CashExpensesDB.CashExpenses.DeleteOnSubmit(item);
    }
    public void deleteDC(Guid servicedetailid)
    {
        CashExpensesDB.sp_deleteDefaultCost(servicedetailid);
    }
    public void submit()
    {
        CashExpensesDB.SubmitChanges();
    }
}

【问题讨论】:

    标签: c# linq-to-sql garbage-collection dispose out-of-memory


    【解决方案1】:

    您应该处置您的DataContext。我看不到它在任何地方被删除,因此连接将保持打开状态,并且可能会保留引用(防止 GC 拾取它们)。这可能是导致问题的原因。如果您不想手动处理,可以在using 块内执行事务。

    根据业务层更新进行编辑 -

    您可以像这样将方法包装在 using 块中:

    public void insert(CashExpense item)
    {    
       using(CEADataStoreDataContext CashExpensesDB = new CEADataStoreDataContext())
       {
           CashExpensesDB.CashExpenses.InsertOnSubmit(item); 
           CashExpensesDB.SubmitChanges();
       }
    }
    

    【讨论】:

    • 嗨,我该如何处理数据上下文?我的业务层上有一个单独的课程。一会儿再补充。。
    • 你可以简单地调用datacontext.Dispose方法——msdn.microsoft.com/en-us/library/…
    • 嗨,我已经添加了我的业务层类。请看一下谢谢。
    • 这行得通吗? public void submit() { CashExpensesDB.SubmitChanges(); CashExpensesDB.Dispose(); }
    • 你可以像上面一样更新你的其他方法。基本上,您只在需要时打开 DataContext,并在不需要时立即关闭它。一旦到达块的末尾,Using 块将自动为您调用 Dispose。看看这是否有助于修复错误。
    【解决方案2】:

    将空值分配给引用您的对象的变量,使用GC.Collect(); 强制垃圾回收。您可能需要连续调用两次以加快不可访问对象的速度。

    【讨论】:

    • tblCashExpenses = null;然后我添加 GC.COllect() 2x?在我的尝试块上?
    • @anonymous1110 是的,看看这是否有帮助。
    【解决方案3】:

    设置对象为null,然后调用:

    GC.Collect(); GC.WaitForPendingFinalizers();

    【讨论】:

    • 这不起作用,因为单个 GC.Collect() 调用只会将对象移动到下一代。没有办法保证 GC.Collect() 甚至可以做某事..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多