Гарантия System.Timers.Timer завершенC#

Место общения программистов C#
Ответить
Anonymous
 Гарантия System.Timers.Timer завершен

Сообщение Anonymous »

У меня есть таймер, который я пытаюсь закрыть в методе удаления, но мне нужно быть на 100% уверенным, что он завершил работу и у нас больше нет случайных обратных вызовов к ElapsedEventHandler.
Я знаю, что вы не могу проверить, завершились ли обратные вызовы, поэтому я пытаюсь охватить все основы, чтобы гарантировать, что сбоев не произойдет и все сообщения будут удалены из моей очереди.
Я реализовал bool StopTimer, поэтому таймер не перезапустится, пока я утилизирую.
У меня есть метод SemaphoreSlim, блокирующий истекшие таймеры.
Я установил задержку, равную 2-кратному интервалу времени, истекшему таймерами, чтобы гарантировать таймер должен был завершить свой последний цикл.
Я также не уверен, правильный ли это подход, или мне следует просто остановить таймер и позволить GC позаботиться об очистке?< /p>
public class MessageWriter : IDisposable
{
public delegate void WriteMessageDelegate(OutputMessage messageQueue);
private ConcurrentQueue MessageQueue = new ConcurrentQueue();
public WriteMessageDelegate OutputToDevice;

private System.Timers.Timer WriteTimer { get; set; }
public int TimerInterval { get; set; }
private SemaphoreSlim WritingMessages;
private bool RunTimer { get; set; }

private bool _disposed = false;

public MessageWriter(double timerInterval)
{
TimerInterval = TimerInterval;

RunTimer = true;

WritingMessages = new SemaphoreSlim(1);

WriteTimer = new System.Timers.Timer();
WriteTimer.AutoReset = false;
WriteTimer.Interval = TimerInterval;
WriteTimer.Elapsed += WriteTimerElapsed;
}

private void WriteTimerElapsed(object sender, ElapsedEventArgs e)
{
try
{
WritingMessages.Wait();

EmptyQueue();

if (RunTimer)
WriteTimer.Start();
}
catch (Exception)
{
//Nothing we can do here, this is the logger
Console.WriteLine("Exception with Log timer - : " + ex.Message);
}
finally
{
WritingMessages.Release();
}
}

private void EmptyQueue()
{
while (MessageQueue.TryDequeue(out var message))
{
OutputToDevice?.Invoke(message);
}
}

protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;

if (disposing)
{
}

//Prevent timer running again
RunTimer = false;

//Disable timer if its running
if (WriteTimer != null)
{
WriteTimer.Enabled = false;
WriteTimer.Stop();
WriteTimer.Dispose();
}

//Wait for double the timer interval
System.Threading.Thread.Sleep(TimerInterval + TimerInterval);

//Wait until this message writer has finished
WritingMessages.Wait();

//Release the semaphore so the timer can run again if it needs to
WritingMessages.Release();

//Get rid of any messages left in the queue
EmptyQueue();

//Dispose of the delegate
OutputToDevice = null;

// Free any unmanaged objects here.
_disposed = true;
}

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

~MessageWriter()
{
Dispose(false);
}
}


Подробнее здесь: https://stackoverflow.com/questions/788 ... s-finished
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»