I've tried to keep the code as short as possible:
public partial class Form1 : Form
{
public delegate void Transformer (TimeSpan distFuture, int alarmNum);
Transformer waitDelegate = setWaitable1;
static WaitableTimer wtAlarm1;
static WaitableTimer wtAlarm2;
static WaitableTimer wtAlarm3;
static WaitableTimer wtAlarm4;
static WaitableTimer wtAlarm5;
static void WakeupProc(object state, DateTime eventTime)
{
//Console.WriteLine("Current time is {0}", DateTime.Now);
//Console.WriteLine("Event fired at {0}", eventTime);
Debug.Print("Callback");
MessageBox.Show("Callback");
}
static void setWaitable1(TimeSpan distFuture, int alarmNum)
{
if(distFuture.TotalMinutes > 0)
{
switch (alarmNum)
{
case 1:
if (wtAlarm1 == null)
{
/*
/* This block executes when the form loads. It works fine. I see a message box that comes
/* up on the screen when the thread stops blocking and the callback is triggered
*/
wtAlarm1 = new WaitableTimer(true, "SepysAlarmV1-" + alarmNum.ToString());
int rslt = wtAlarm1.Change(distFuture, 0, WakeupProc, null, true);
if (rslt == WaitableTimer.ErrorNotSupported)
{
MessageBox.Show("Computer does not support resume.");
}
MessageBox.Show("Waitable timer created. Waiting for trigger.");
wtAlarm1.WaitOne();
Thread.Sleep(5000);
}
else if (wtAlarm1 != null)
{
/* This code executes when I make an edit. So the condition here is that wtAlarm1 is already
/* set by way of new WaitableTimer(). When the thread stops blocking and the callback WakeupProc executes
/* I am getting an exception occuring.
*/
wtAlarm1.Cancel();
wtAlarm1 = null;
wtAlarm1 = new WaitableTimer(true, "SepysAlarmV1-" + alarmNum.ToString());
int rslt = wtAlarm1.Change(distFuture, 0, WakeupProc, null, true);
if (rslt == WaitableTimer.ErrorNotSupported)
{
MessageBox.Show("Computer does not support resume.");
}
MessageBox.Show("Waitable timer edited. Waiting for callback.");
wtAlarm1.WaitOne();
Thread.Sleep(5000);
}
break;
default:
//Console.WriteLine("Default case");
break;
}
}
else
{
MessageBox.Show("Time span too short to set wake timer for alarm "+"SepysAlarmV1-"+alarmNum.ToString());
}
}
}
When I make an edit there is an exception occurring when the thread stops blocking and the callback delegate executes.
It is saying:
A callback was made on a garbage collected delegate of type 'Name!Namespace.Win32WaitableTimer+TimerAPCProc::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
Why is this happening and what can I do to prevent it from happening?
Thank you.
No comments:
Post a Comment