anonymous1110
anonymous1110

Reputation: 885

How to Force Disposal of Objects / GC

How do you force objects to dispose after use in order to free up memory? And, how do you force GC to collect?

Here's my Save Code. I've noticed that, every time I execute this function, my memory consumption goes up that would eventually caused an out of memory error after a couple of hits.

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);
    }
}

Here's My business layer class

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();
    }
}

Upvotes: 3

Views: 13259

Answers (3)

Greg Dolley
Greg Dolley

Reputation: 21

Set the object to null, then call:

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

Upvotes: 1

keyboardP
keyboardP

Reputation: 69372

You should dispose your DataContext. I can't see it being removed anywhere, so the connection will remain open and references may be held on to (preventing the GC from picking them up). This may be what's causing the problem. If you don't want to dispose manually, you can perform the transaction within a using block.

Edit in response to Business Layer update -

You can wrap the methods in using blocks like this:

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

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726839

Assign nulls to variables referencing your objects, the use GC.Collect(); to force garbage collection. You may need to call it twice in a row to speed non-accessible objects through the process.

Upvotes: 4

Related Questions