1

我一直在从事一个使用表适配器和数据集来访问访问数据库的项目。我即将完成并从 Visual Studio 运行代码分析,它提出了一些关于需要在我使用这些方法的特定类上实现 IDisposable 的错误。虽然我已经查看了一些关于使用 dispose 方法或使用 using 块的不同内容,但我不确定如何使其工作。数据集和表适配器被创建为供整个类使用的全局变量,许多类将调用其他类,这些类也将使用不同的表适配器和数据集。我试过创建一个 Dispose 方法,但我不知道什么时候调用它,我想知道是否在错误的时间调用它会导致我的程序崩溃。

   using System;
   using System.Collections.Generic;
   using System.Linq;
    using System.Text;

 namespace recipeDataBase 
 {
     class NewRecipe : IDisposable
     {
         recipiesNewDataSet recipeDataSet = new recipiesNewDataSet();
         recipiesNewDataSetTableAdapters.RecipeTableAdapter recipeTableAdapter = new      recipiesNewDataSetTableAdapters.RecipeTableAdapter();
    recipiesNewDataSetTableAdapters.RecipeIngredientTableAdapter recipeIngredientTableAdapter = new recipiesNewDataSetTableAdapters.RecipeIngredientTableAdapter();
    recipiesNewDataSetTableAdapters.RatingTableAdapter ratingTableAdapter = new recipiesNewDataSetTableAdapters.RatingTableAdapter();
    recipeDataBase.recipiesNewDataSetTableAdapters.IngredientTableAdapter ingredientTableAdapter = new recipiesNewDataSetTableAdapters.IngredientTableAdapter();
    private RecipeInfo newRecipe;
    private RatingNum originalRatingNum;
    private RatingNum newRating;
    private RecipeInfo originalRecipe;
    private string[] ingredients;

    public NewRecipe(RecipeInfo incommingNewRecipe, RatingNum IncommingNewRating, string[] incommingIngredients)
    {
        newRecipe = incommingNewRecipe;
        newRating = IncommingNewRating;
        ingredients = incommingIngredients;
        CreateNewRecipe();
        UpdateNewRecipe();
    }
    public void CreateNewRecipe()
    {
        originalRatingNum = new RatingNum();
        originalRecipe = new RecipeInfo();
        originalRatingNum.cookingTime = 0;
        originalRatingNum.easeOfCooking = 0;
        originalRatingNum.familyRating = 0;
        originalRatingNum.healthRating = 0;
        originalRatingNum.userRating = 0;

        ratingTableAdapter.Fill(recipeDataSet.Rating);
        ratingTableAdapter.Insert(originalRatingNum.userRating, originalRatingNum.familyRating, originalRatingNum.healthRating, originalRatingNum.easeOfCooking, originalRatingNum.cookingTime);
        Query getNewRecipeNumbers = new Query();
        int newRatingNumber = getNewRecipeNumbers.newRatingNum();



        originalRatingNum.ratingNum = newRatingNumber;
        newRating.ratingNum = newRatingNumber;
        newRecipe.ratingNum = newRatingNumber;
        originalRecipe.recipeName = "newRecipe";
        originalRecipe.nationality = "newRecipe";
        originalRecipe.recipeEvent = "newRecipe";
        originalRecipe.source = "newRecipe";
        originalRecipe.type = "newRecipe";
        originalRecipe.servings = "0";
        originalRecipe.ratingNum = newRatingNumber;


        recipeTableAdapter.Fill(recipeDataSet.Recipe);
        recipeTableAdapter.Insert(originalRecipe.recipeName, originalRecipe.nationality, originalRecipe.recipeEvent, originalRecipe.source, originalRecipe.type, originalRecipe.servings, originalRecipe.ratingNum); 
        int newRecipeNum = getNewRecipeNumbers.newRecipeNum();
        newRecipe.recipeNum = newRecipeNum;
        originalRecipe.recipeNum = newRecipeNum;
        recipeDataSet.AcceptChanges();
    }

    public void UpdateNewRecipe()
    {
        UpdateRatingNum updateRatingNum = new UpdateRatingNum(originalRatingNum, newRating);
        UpdateRecipe updateRecipe = new UpdateRecipe(newRecipe, originalRecipe);

        UpdateIngredients updateIngredients = new UpdateIngredients(ingredients);
        UpdateRecipeIngredient updateRecpeIngredients = new UpdateRecipeIngredient(ingredients, newRecipe.recipeNum);
        recipeDataSet.AcceptChanges();

    }


    public void Dispose()
    {
        ratingTableAdapter.Dispose();
        recipeTableAdapter.Dispose();
        recipeTableAdapter.Dispose();
        ingredientTableAdapter.Dispose();
        recipeDataSet.Dispose();
        throw new NotImplementedException();
    }
}

}

如您所见,我确实实现了 Idisposable 并使用自动创建的方法将所有表适配器和数据集放入其中以进行处置,但是我如何使用它以及在哪里使用它?

谢谢您的帮助

克雷格

4

3 回答 3

2

正常模式:

using (var nr = new NewRecipe() )
{
   ...
}

但这里有一些注意事项:

  • DataSet 和 DataAdapter 上的 IDisposable 接口是假的,跳过它们不会损失太多。
  • 您的类具有存储库和域对象的双重角色。考虑将其分为 2 个类。
于 2012-10-24T13:05:36.280 回答
1

如其他答案中所述,使用实现的对象的正确方法是IDisposable使用 using 块,如下所示:

using (var recipe = new NewRecipe())
{
    //put your code that uses recipe here
}

我想指出的是 IDisposable 模式的正确实现。请注意,在MSDN 文章中有一个 IDisposable 接口的完整示例。

class Recipe : IDisposable
{
    bool isDisposed = false;
    TableAdapter myDisposableMember;

    public void Dispose()
    {
        Dispose(true);
        GC.SupressFinalize(this);
    }

    public virtual Dispose(bool isDisposing)
    {
        if (!isDisposed) //only clean up once
        {
            //clean up unmanaged resource here
            //in this case we don't have any

            //clean up managed resources (IE those that implemetn IDisposable only if
            //Dispose() was called (not the case when invoked during finalisation)
            if (isDisposing)
            {
                if(myDisposableMember == null)
                {
                    myDisposableMember.Dispose()
                    myDisposablemember = null;
                }
            }

            //mark this instance as cleaned up
            isDisposed = true;
        }
    }

    //if our class has any unmanaged resources you implement a destructor to guarantee
    //that they're freed. We don't have any here so we don't implement it.
    //~Recipe()
    //{
    //    Dispose(false);
    //}
}

另请注意,在完成过程中您永远不应该抛出异常(IE: ~Recipe())。因此Dispose(bool)永远不应该抛出异常。

于 2012-10-24T13:38:23.123 回答
0

正确的使用方法是using。只是不要把它拿在手里——

using(DataAdapter ratingTableAdapter = new DataAdapter())
{

}

一旦代码从 using 块中出来,ratingTableAdapter将被释放。

于 2012-10-24T13:09:37.127 回答