Я использовал шаблон наблюдателя для своего приложения.
У меня есть субъект, в котором есть один System.Timers.Timer объект с именем 'tmr' .Тиковое событие этого таймера срабатывает через каждые 60 секунд .Об этом событии я буду уведомлять всех своих наблюдателей, которые прикреплены к моей теме.Я использовал цикл for для итераций в моем списке наблюдателей, а затем запустил метод обновления наблюдателей.
Предположим, у меня есть 10 наблюдателей, прикрепленных к моему предмету.
Каждому наблюдателю для завершения требуется 10 секунд.его обработка.
Теперь уведомление, выполняемое в цикле for, заставляет последний метод Update Observer вызываться через 90 секунд.то есть метод обновления следующего наблюдателя вызывается только после того, как предыдущий завершил свою обработку.
Но это не то, что я хотел в моем приложении.Мне нужно, чтобы все мои методы обновления наблюдателей запускались мгновенно при срабатывании таймера.Так что ни один наблюдатель не должен ждать.Я надеюсь, что это может быть сделано Threading.
Итак, я изменил код на,
// Fires the updates instantly
public void Notify()
{
foreach (Observer o in _observers)
{
Threading.Thread oThread = new Threading.Thread(o.Update);
oThread.Name = o.GetType().Name;
oThread.Start();
}
}
Но у меня есть два сомнения в моем уме:
Если есть 10 наблюдателей И мойинтервал таймера составляет 60 секунд. Тогда оператор new Thread () будет запускаться 600 раз.
Эффективно ли и рекомендуется ли создавать новые потоки на каждом такте таймера?
Что, если мои наблюдатели тратят слишком много времени на завершение своей логики обновления, т.е.60seconds.Означает, что отметка таймера происходит перед обновлением наблюдателей.Как я могу контролировать это?
Я могу опубликовать образец кода .. если требуется ...
Код, который я использовал ..
using System;
using System.Collections.Generic;
using System.Timers;
using System.Text;
using Threading = System.Threading;
using System.ComponentModel;
namespace singletimers
{
class Program
{
static void Main(string[] args)
{
DataPullerSubject.Instance.Attach(Observer1.Instance);
DataPullerSubject.Instance.Attach(Observer2.Instance);
Console.ReadKey();
}
}
public sealed class DataPullerSubject
{
private static volatile DataPullerSubject instance;
private static object syncRoot = new Object();
public static DataPullerSubject Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new DataPullerSubject();
}
}
return instance;
}
}
int interval = 10 * 1000;
Timer tmr;
private List<Observer> _observers = new List<Observer>();
DataPullerSubject()
{
tmr = new Timer();
tmr.Interval = 1; // first time to call instantly
tmr.Elapsed += new ElapsedEventHandler(tmr_Elapsed);
tmr.Start();
}
public void Attach(Observer observer)
{
_observers.Add(observer);
}
public void Detach(Observer observer)
{
_observers.Remove(observer);
}
// Fires the updates instantly
public void Notify()
{
foreach (Observer o in _observers)
{
Threading.Thread oThread = new Threading.Thread(o.Update);
oThread.Name = o.GetType().Name;
oThread.Start();
}
}
private void tmr_Elapsed(object source, ElapsedEventArgs e)
{
tmr.Interval = interval;
tmr.Stop(); // stop the timer until all notification triggered
this.Notify();
tmr.Start();//start again
}
}
public abstract class Observer
{
string data;
public abstract void Update();
public virtual void GetDataFromDBAndSetToDataSet(string param)
{
Console.WriteLine("Processing for: " + param);
data = param + new Random().Next(1, 2000);
Threading.Thread.Sleep(10 * 1000);//long work
Console.WriteLine("Data set for: " + param);
}
}
public sealed class Observer1 : Observer
{
private static volatile Observer1 instance;
private static object syncRoot = new Object();
public static Observer1 Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Observer1();
}
}
return instance;
}
}
Observer1()
{
}
public override void Update()
{
base.GetDataFromDBAndSetToDataSet("Observer1");
}
}
public sealed class Observer2 : Observer
{
private static volatile Observer2 instance;
private static object syncRoot = new Object();
public static Observer2 Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Observer2();
}
}
return instance;
}
}
Observer2()
{
}
public override void Update()
{
base.GetDataFromDBAndSetToDataSet("Observer2");
}
}
}
Спасибо и всего наилучшего.