В приложении, которое я разрабатываю, я буду использовать 2 потока для выполнения различных операций. (Я не буду вдаваться в подробности здесь.) Эти потоки работают в циклах, проверяя, есть ли работа, которая должна быть выполнена, выполняя работу, вычисляя время, необходимое для ожидания и ожидания. (Смотрите ниже)Могу ли я вызвать Monitor.Pulse из другого класса в C#
public Global : System.Web.HttpApplication
{
private static Thread StartingDateThread;
private static Thread DeadlineDateThread;
private static object o1;
private static object o2;
public static Thread GetStartingDateThreadInstance
{
get
{
if(StartingDateThread==null)
{
StartingDateThread=new Thread(new ThreadStart(MonitorStartingDates));
}
return StartingDateThread;
}
}
public static Thread GetDeadlineThreadInstance
{
get
{
if(DeadlineDateThread==null)
{
DeadlineDateThread=new Thread(new ThreadStart(MonitorDeadlines));
}
return DeadlineDateThread;
}
}
public static object GetFirstObjectInstance
{
get
{
if(o1==null)
{
o1=new object();
}
return o1;
}
}
public static object GetSecondObjectInstance
{
get
{
if(o2==null)
{
o2=new object();
}
return o2;
}
}
protected void Application_Start(object sender, EventArgs e)
{
GetStartingDateThreadInstance.Start();
GetDeadlineThreadInstance.Start();
//////////////////////
////Do other stuff.
}
public void MonitorStartingDates()
{
while(true)
{
//Check if there is stuff to do.
//Do stuff if available.
//Check if there will be stuff to do in the future and if there is, check
//the time to wake up.
//If there is nothing to do, sleep for a pre-determined 12 hours.
if(StuffToDoInFuture)
{
Monitor.Enter(GetFirstObjectInstance);
Monitor.Wait(WaitingTime);
Monitor.Exit(GetFirstObjectInstance);
}
else
{
Monitor.Enter(GetFirstObjectInstance);
Monitor.Wait(new TimeSpan(12, 0, 0));
Monitor.Exit(GetFirstObjectInstance);
}
}
}
public void MonitorDeadlines()
{
while(true)
{
//Check if there is stuff to do.
//Do stuff if available.
//Check if there will be stuff to do in the future and if there is, check
//the time to wake up.
//If there is nothing to do, sleep for a pre-determined 3 days and 12 hours.
if(StuffToDoInFuture)
{
Monitor.Enter(GetSecondObjectInstance);
Monitor.Wait(WaitingTime);
Monitor.Exit(GetSecondObjectInstance);
}
else
{
Monitor.Enter(GetSecondObjectInstance);
Monitor.Wait(new TimeSpan(3, 12, 0, 0));
Monitor.Exit(GetSecondObjectInstance);
}
}
}
Как вы можете видеть, что эти две нити запускаются в методе Application_Start в файле asax. Они работают, если есть вещи, которые можно сделать, и затем они подсчитывают время, которое им нужно подождать, а затем они ждут. Однако, поскольку пользователи веб-приложения выполняют операции, новые записи будут вставлены в базу данных, и будут ситуации, когда любой из двух потоков должен будет возобновить работу раньше запланированного. Итак, скажем, у меня есть метод в моем классе DataAccess, который вставляет в базу данных новые данные. (См ниже)
public class DataAccess
{
///////////////
//
public void InsertNewAuction()
{
///Insert new row calculate the time
Monitor.Pulse(Global.GetFirstObjectInstance);
Monitor.Pulse(Global.GetSecondObjectInstance);
///
}
}
Похоже, что это недопустимая операция, потому что на той стадии, когда Monitor.Pulse вызывается из метода InsertNewAuction я получаю исключение. Что-то вроде «Метод синхронизации объекта был вызван из несинхронизированного блока кода». Есть ли способ сделать это? Спасибо за вашу помощь.
Почему бы не использовать модель публикации/подписки? ala ServiceBus – tvanfosson