На какие объекты мы должны использовать метод dispose?C # 4.0 - PullRequest
0 голосов
/ 22 октября 2011

Хорошо, я собираюсь перечислить объекты моего программного обеспечения. В настоящее время использование памяти увеличивается с течением времени, хотя не должно увеличиваться, потому что я не сохраняю никаких ресурсов. Использование только базы данных.

c # 4.0, visual studio 2010

Давайте начнем с объектов. На этих объектах я должен вызывать dispose или использовать «using»

string variable;
int variable;
dataset variable;
HtmlDocument variable;
List<string> variable;
HtmlNode variable;
Uri variable;
DateTime variable;
HtmlWeb variable;
Regex variable;
MatchCollection variable;
bool variable;

фрагмент кода (все, что требуется после метода File.WriteAllText?)

                File.WriteAllText("hatalar/" + UtcTimeNow.Ticks.ToString() + GenerateRandomValue.GenerateRandomValueDefault(10000000) + ".txt", srCrawledUrl + " unknown error page id " + srPageId);

часть кода

                if (irFinishedLast > -1)
            {
                var newTask = Task.Factory.StartNew(() =>
                {
                    fcStartSubPageCrawl(srMainSiteURL, srMainSiteId, irWhichMainTask);
                });
                lock (lockerMainSitesArray)
                {
                    if (MainSitesTaskList[irWhichMainTask, irFinishedLast] != null)
                        MainSitesTaskList[irWhichMainTask, irFinishedLast].Dispose();
                    MainSitesTaskList[irWhichMainTask, irFinishedLast] = newTask;
                }
            }

Хорошо, теперь классы и функции. Открытая статическая функция, которая вызывается многими потоками одновременно. Он находится внутри публичного статического класса.

public static string srInserIntoPagesCommand = "insert into myTable (PageUrl,MainSiteId,CrawlDateInt,CrawlDateChar,CrawlDepth,ExtractedPageId,CrawlStatus) values " +
            "(@PageUrl,@MainSiteId,@CrawlDateInt,@CrawlDateChar,@CrawlDepth,@ExtractedPageId,@CrawlStatus)";

        public static bool InsertIntoPages(string PageUrl, string MainSiteId, string CrawlDateInt, string CrawlDateChar, string CrawlDepth, string ExtractedPageId, string CrawlStatus)
        {
            string srPageUrl = PageUrl;
            string srMainSiteId = MainSiteId;
            string srCrawlDateInt = CrawlDateInt;
            string srCrawlDateChar = CrawlDateChar;
            string srCrawlDepth = CrawlDepth;
            string srExtractedPageId = ExtractedPageId;
            string srCrawlStatus = CrawlStatus;

            if (srCrawlDateInt.Length < 1)
                srCrawlDateInt = "0";
            if (srCrawlDateChar.Length < 1)
                srCrawlDateChar = "null";
            if (srCrawlStatus.Length < 1)
                srCrawlStatus = "0";

            using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand(srInserIntoPagesCommand, connection))
                {
                    cmd.CommandType = CommandType.Text;
                    cmd.Parameters.AddWithValue("@PageUrl", srPageUrl);
                    cmd.Parameters.AddWithValue("@MainSiteId", srMainSiteId);
                    cmd.Parameters.AddWithValue("@CrawlDateInt", srCrawlDateInt);
                    cmd.Parameters.AddWithValue("@CrawlDateChar", srCrawlDateChar);
                    cmd.Parameters.AddWithValue("@CrawlDepth", srCrawlDepth);
                    cmd.Parameters.AddWithValue("@ExtractedPageId", srExtractedPageId);
                    cmd.Parameters.AddWithValue("@CrawlStatus", srCrawlStatus);
                    try
                    {
                        connection.Open();
                        cmd.ExecuteNonQuery();
                    }
                    catch (Exception E)
                    {
                        DateTime UtcTimeNow = DateTime.UtcNow;
                        File.WriteAllText("pageshatalar/" + UtcTimeNow.Ticks.ToString() + GenerateRandomValue.GenerateRandomValueDefault(1000000) + ".txt", "InsertIntoPages \r\n\r\n" + E.Message.ToString() + "\r\n\r\n" + srPageUrl);
                        return false;
                    }
                }
                connection.Close();
            }
            return true;
        }

публичная статическая связь с базой данных для запросов на выборку, в основном внутри публичного статического класса

public static string srConnectionString = "server=localhost;database=mydb;uid=sa;pwd=mypw; Max Pool Size=20000; Pooling=True;";

public static DataSet db_Select_Query(string strQuery)
{
    DataSet dSet = new DataSet();
    try
    {
        using (SqlConnection connection = new SqlConnection(srConnectionString))
        {
            connection.Open();
            using (SqlDataAdapter DA = new SqlDataAdapter(strQuery, connection))
            {
                DA.Fill(dSet);
            }
            connection.Close();
        }
        return dSet;
    }
    catch
    {
        DateTime UtcTimeNow = DateTime.UtcNow;
        File.WriteAllText("sqlhatalar/" + UtcTimeNow.Ticks.ToString() + GenerateRandomValue.GenerateRandomValueDefault(1000000) + ".txt", strQuery);
        return null;
    }
}

Ответы [ 3 ]

2 голосов
/ 22 октября 2011

Вы не случайно называете распоряжаться какой-либо конкретной вещью.Оператор using и метод .Dispose предназначены для объектов, которые реализуют интерфейс IDisposable

 public interface IDisposable
 {
       void Dispose();
 }

Беглый осмотр вашего списка верхних переменных показывает, что ни одна из этих переменных не реализует IDisposable.Вы не можете вызывать Dispose() для них, а также не можете заключать их в оператор using.

Кроме того, вызов Dispose() для фактических одноразовых объектов не является формойуправление памятью, оно предназначено для освобождения неуправляемых ресурсов.Сборщик мусора не связан с этим.Если у вас есть проблемы с управлением памятью, это может показать, что вы слишком долго поддерживаете слишком много объектов.Вам необходимо изучить область действия и время жизни, размеры коллекций и т. Д., Поскольку именно они будут добавлять к вашему мусору.

Ваша проблема с памятью не обнаруживается в отображаемом коде, за исключением того, что вы могли бы бытьобработка и возврат больших массивов данных, которые ваши абоненты могут хранить дольше, чем это необходимо.Или это может быть что-то совершенно не связанное с каким-либо отображаемым кодом.Если у вас есть проблема с памятью, запустите профилировщик памяти, чтобы определить проблемные области. Для этого вы можете получить бесплатные пробные версии профилировщиков из Red Gate или JetBrains.

1 голос
/ 22 октября 2011

Если по какой-то странной причине вы не знаете во время выполнения, реализован ли объект утилизации, вы можете использовать эту функцию утилизации:

/// ---- IsDisposable --------------------------------
///
/// <summary>
/// returns true if an object is disposable, false if not
/// you can optionally dispose of it immediately
/// </summary>

public static Boolean IsDisposable(Object Item, Boolean DeleteIfDisposable)
{
    if (Item is IDisposable)
    {
        if (DeleteIfDisposable)
        {
            IDisposable DisposableItem;
            DisposableItem = (IDisposable)Item;
            DisposableItem.Dispose();
        }
        return true;
    }
    else
        return false;
}
1 голос
/ 22 октября 2011

Вы не можете вызвать Dispose() для большинства объектов в вашем списке, потому что они не предоставляют метод Dispose().Вы должны вызывать Dispose() для объекта любого типа, который реализует интерфейс IDisposable.Вот и все.

...