Предположим, у меня есть одна форма с именем mainFrm и объект, называемый objectA, который содержит текущие потоки. Когда произойдет какое-либо из этих двух событий, моя программа должна закрыть:Завершить работу потока, когда пользователь нажимает кнопку «X» в форме
(1). Пользователь нажимает кнопку «X» в mainFrm (так что mainFrm.FormClosing поднимается)
(2). события (назовем его «connectionClosed») поднимается в Objecta
Таким образом, независимо от того, что, если (1) или (2) срабатывает, эта цепь событий всегда должен включать:
- прекращение любого объекта, лежащего в основе потока. (Я уже знаю, как изящно завершает их с кодом, расположенным внутри Objecta)
- Конечно, MainFrm ценой закрытия
Какой самый лучший способ решить эту проблему?
ЭТО КАК РЕШИТЬ IT
Не знаю, почему этот вопрос не был хорошо принят сообществом. Я думал, что это было достаточно ясно и понятно. Вот как я решил это, я надеюсь, что это также помогает лучше определить, что я имел в виду. Если у вас есть какой-либо другой запрос, просто дайте мне знать =)
В классе формы:
...
this.FormClosed += objectA.kill;
objectA.connectionClosed +=closeForm;
...
private void closeForm(object sender, FormClosedEventArgs e)
{
try
{
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
}
catch { }
}
В классе Objecta в:
...
//connectionClosed is raised in different parts of objectA's threads code
connectionClosed += killClient;
...
public void killClient(object sender, FormClosedEventArgs e)
{
//event should go past this point just once
if (!_connectionClosed)
{
_connectionClosed = true;
try
{
... //close connection killing all threads
}
catch { }
}
}
Согласно (1) и (2) usecases заявил в начале, это то, что должно произойти (если я не ошибаюсь)
(1). Пользователь нажимает кнопку «X» -> закрывается форма -> formclosed поднят -> выполняется делегат метода objectA.kill -> внутренние потоки поднимают некоторые события закрытого соединения, которые будут запускать больше выполнения objectA.kill, но это не принесет никакого ущерба to volatile bool _connectionClosed (конечно, поскольку есть попытка try/catch, которая будет работать в любом случае, но мне просто не нужно больше выполнять такой код) -> потоки завершаются единственным полным выполнением объектаA.kill -> SUCCESS
(2). Сервер закрывает соединение или сетевую ошибку. - Внутренние потоки objectA обнаруживают ошибку соединения и увеличивают несколько соединений. Закрытые события -> разные потоки будут пытаться выполнить делегат метода objectA.kill. -> в то же время в основной форме выполняется closeForm, закрывая форму -> это также запускает другое выполнение objectA.kill (спасибо this.FormClosed + = _client.killClient;) -> снова, это не наносит вреда, поскольку _connectionClosed volatile bool позволит только одному потоку фактически выполнить код (первый, который поднял событие) -> потоки изящно прекращаются единственным полным выполнением объекта A.убить -> УСПЕХ
Следующий шаг должен найти более удобный способ, так что connectionClosed может быть вырос только один раз, я Google за это прямо сейчас =)
Совет: В 'connectionClosed', вызовите' mainFrm.Close() '. Тогда это упрощает первую ситуацию. –