У меня есть форма с элементом управления, чтобы отображать некоторые пользовательские объекты. В форме я подписываюсь на событие AddObject, которое добавляет объекты в список ToAdd, когда они входят с сервера. Я настраиваю таймер для запуска каждые 10 секунд, чтобы скопировать объекты из списка ToAdd в список отображения (было более эффективно добавлять элементы навалом в элемент управления, чем 1 за раз, когда они вошли), который связан с контроль над моей формой, затем я очищаю список ToAdd. Безопасно ли иметь замок внутри BeginInvoke? Есть ли лучший способ сделать это?Безопасно ли иметь блокировку() внутри вызова BeginInvoke?
private System.Threading.Timer aTimer;
private readonly Object sync = new Object();
List<object> ToAdd = new List<object();
List<object> Display = new List<object();
private void Init()
{
TimerCallback tcb = IntermittentProcessMessages;
aTimer = new System.Threading.Timer(tcb, null, 1000, 100);
Server.MessageReceived += AddObject;
}
private void AddObject(object t)
{
lock (sync)
{
try
{
ToAdd.Add(t);
}
finally() {}
}
}
private void IntermittentProcessMessages(object source)
{
try
{
if (this.IsHandleCreated == false)
{
return;
}
this.BeginInvoke((Action)delegate()
{
lock (sync)
{
if (ToAdd.Count > 0)
{
ToAdd.ForEach(f => Display.Add(f));
ToAdd.Clear();
}
}
}
}
finally(){}
}
Это выглядит хорошо для меня. – Gabe
Вы используете тот же объект синхронизации в AddObject и BeginInvoke. Используйте два разных объекта синхронизации, чтобы они не были заблокированы друг для друга. –
@UnmeshKondolikar, Они * должны * блокировать друг друга, так как они защищают список 'Display'. –