我一直在研究一个使用表适配器和数据集来访问访问数据库的项目。我已经接近完成并从visual studio运行代码分析,它出现了一些关于需要在我使用这些方法的特定类上实现IDisposable的错误。虽然我已经看了一些关于使用dispose方法或使用using块的不同内容,但我不确定如何使这个工作。数据集和表适配器被创建为全类使用的全局变量,许多类将调用其他类,这些类也将使用不同的表适配器和数据集。我已经尝试创建一个Dispose方法,但我不知道何时调用它,我想知道是否在错误的时间调用它会导致我的程序崩溃。以下是我需要实现Idisposable的其中一个类的示例:
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并使用自动创建的方法将所有表适配器和数据集放在那里进行处置,但是如何使用它以及在哪里使用?
感谢您的帮助
克雷格
答案 0 :(得分:2)
正常模式:
using (var nr = new NewRecipe() )
{
...
}
但这里有一些注意事项:
答案 1 :(得分:1)
正如其他答案中所提到的,实现IDisposable
的对象用法的正确方法是使用如下的使用块:
using (var recipe = new NewRecipe())
{
//put your code that uses recipe here
}
我想指出的是IDisposable模式的正确实现。请注意,MSDN article for the IDisposable interface上有一个完整的示例。
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)
不应该抛出异常。
答案 2 :(得分:0)
正确的使用方式是using
。只是不要把它拿在手里 -
using(DataAdapter ratingTableAdapter = new DataAdapter())
{
}
一旦代码从使用块中出来,ratingTableAdapter 就会被处理掉。