1

В настоящее время я пишу приложение, которое в основном использует DispatcherTimer для эмуляции функции секундомера. Хотя мой DispatcherTimer работает в приложении, использование памяти моего приложения увеличивается до 100 МБ менее чем за 10 минут, что особенно странно, учитывая, насколько просты функциональность приложения. Это, как правило, не было проблемой, кроме того, что быстрое увеличение использования памяти приложения приводит к сбою и завершению работы. Я смотрел по всему Интернету и неоднократно сталкивался с статьями, подтверждающими существование утечки памяти DispatcherTimer, однако все исправления этой утечки памяти состоят в остановке DispatcherTimer, когда она больше не нужна. Моя утечка памяти происходит, когда DispatcherTimer по-прежнему нужен, а не когда он случайно оставлен. Мне нужно разрешить пользователям поддерживать свою работу секундомера в течение как бы долго они ни выбрали, поэтому остановка DispatcherTimer, когда она больше не нужна, больше не делает для меня. Я попытался добавить GC.Collect() в конце обработчика событий TimerTick, однако, похоже, это тоже не так.DispatcherTimer продолжает увеличивать использование памяти до тех пор, пока не завершится авария приложения

public MainPage() 
    { 
     InitializeComponent(); 
     PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled; 
     Timer.Stop(); 
     Timer.Interval = new TimeSpan(0, 0, 1); 
     Timer.Tick += new EventHandler(TimerTick); 
     Loaded += new System.Windows.RoutedEventHandler(MainPage_Loaded);   

    } 

void TimerTick(object sender, EventArgs e) 
    { 

     timeSpan1 = DateTime.Now.Subtract(StartTimer); 
     timeSpan2 = DateTime.Now.Subtract(StartTimer2); 
     WatchHour.Text = timeSpan1.Hours.ToString(); 
     WatchMinute.Text = timeSpan1.Minutes.ToString(); 
     WatchSecond.Text = timeSpan1.Seconds.ToString(); 
     SecondaryHour.Text = timeSpan2.Hours.ToString(); 
     SecondaryMinute.Text = timeSpan2.Minutes.ToString(); 
     SecondarySecond.Text = timeSpan2.Seconds.ToString(); 


     if (WatchHour.Text.Length == 1) WatchHour.Text = "0" + WatchHour.Text; 
     if (WatchMinute.Text.Length == 1) WatchMinute.Text = "0" + WatchMinute.Text; 
     if (WatchSecond.Text.Length == 1) WatchSecond.Text = "0" + WatchSecond.Text; 


     if (SecondaryHour.Text.Length == 1) SecondaryHour.Text = "0" + SecondaryHour.Text; 
     if (SecondaryMinute.Text.Length == 1) SecondaryMinute.Text = "0" + SecondaryMinute.Text; 
     if (SecondarySecond.Text.Length == 1) SecondarySecond.Text = "0" + SecondarySecond.Text; 

    } 

Это мой TimerTick обработчик событий и немного моего MainPage конструктора, в текстовые поля, присутствующие в обработчик событий отображается время, прошедшее с начала секундомера. Я делаю что-то совершенно неправильное здесь, что вызывает такое огромное увеличение памяти? Ранее я думал, что проблема заключается в том, что TextBoxs каким-то образом кэшировали свое предыдущее содержимое по умолчанию в сочетании с быстрыми изменениями текста из-за функциональности секундомера, однако, после полного удаления TextBoxes из моего приложения и анализа его, я совершенно уверен, что они aren Проблема. Как указано выше, добавление GC.Collect() в конце этого обработчика TimerTick не сделало ничего, чтобы уменьшить использование моей памяти. Кто-нибудь имеет представление о том, как я могу уменьшить использование памяти с помощью DispatcherTimer, возможно, каким-то образом манипулируя функцией GC, чтобы на самом деле работать?

Заранее благодарен!

+0

Как насчет остановки таймера в начале события тика, И снова начинать его в конце? –

+1

Я не думаю, что проблема связана с кодом выше. Преступник это где-то еще, я подозреваю. BTW использует 'WatchHour.Text = timeSpan1.Hours.ToString («00»); 'для достижения правильного форматирования по мере необходимости. –

+0

Возникла ли ошибка приложения, если вы позволили ему работать, или память перестает увеличиваться в какой-то момент? –

ответ

0

Я, наконец, изолировал ядро ​​утечки памяти, проблема была не в моем DispatcherTimer, а вместо этого с моим контроллером AdRotator. Проблема была обнаружена на стороне разработчиков AdRotator, и в настоящее время я использую другой рекламный блок, пока проблема не будет устранена.

Спасибо вам за помощь, я очень ценю ваше время и силы!

+0

Попытайтесь отметить этот вопрос как ответ ... –

+0

В нем говорится, что мне нужно подождать 2 часа, чтобы отметить мой собственный ответ в качестве принятого нами ответа: S – user2637236

0

Почему вы объявляете промежуток времени1 и timespan2 вне события таймера? Выглядит ли память лучше, если вы создаете его внутри обработчика событий

+0

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

0

Не могли бы вы, пожалуйста, попробуйте следующий фрагмент кода,

Шаг: 1 Добавить кнопку и TextBlock в XAML первой.

Шаг: 2 Используйте следующие пространства имен:

using System.Diagnostics; // for Stopwatch API Access 

Шага: 3 используйте нижеуказанный фрагмент кода:

public partial class WmDevStopWatch : PhoneApplicationPage 
    { 
     Stopwatch stopWatch = new Stopwatch(); 
     DispatcherTimer oTimer = new DispatcherTimer(); 

     public WmDevStopWatch() 
     { 
      InitializeComponent(); 

      oTimer.Interval = new TimeSpan(0, 0, 0, 0, 1); 
      oTimer.Tick += new EventHandler(TimerTick); 

     } 

     void TimerTick(object sender, EventArgs e) 
     { 
      Dispatcher.BeginInvoke(() => 
      { 
       string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", 
        stopWatch.Elapsed.Hours, stopWatch.Elapsed.Minutes, stopWatch.Elapsed.Seconds, 
        stopWatch.Elapsed.Milliseconds/10); 

       textBlock1.Text = elapsedTime; 
      }); 
     } 


     private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      stopWatch.Start(); 
      oTimer.Start(); 
     } 
    } 

Надеется, что это работает для вас.

Оставьте свой отзыв для этого же.