У меня есть консольное приложение, в котором у меня есть подключение к третьей стороне службы Windows на удаленном сервере с помощью tcp/ip.
Иерархия вызова нравится:
static class Program
{
[MTAThread]
static void Main()
{
MyApplication.Start();
Метод Start
public static void Start()
{
lock (SyncVar)
{
ThreadStart ts = new ThreadStart(MainCode);
MainCodeThread = new Thread(ts);
MainCodeThread.IsBackground = false;
MainCodeThread.Start();
Деталь основного потока:
private static void MainCode()
{
try
{
// connect to the remote server, against a windows service
TelephonyServer tServer = new TelephonyServer(sIpaddress, "username", "password");
while (true)
{
Task consumer = Task.Run(() =>
{
if (data != "")
{
ProcessEachChannel(data);
});
Task producer = Task.Run(() =>
{
// blah blah
});
В методе ProcessEachChannel
мы имеем
public bool ProcessEachChannel(string workItem)
{
ChannelResource cr = tServer.GetChannel();
// blah blah
}
Теперь приложение работает хорошо. Однако, если я нажму красным краем выхода приложения или нажмите кнопку "Отключить отладку" в Visual Studio, ресурсы ChannelResource cr
не будут уничтожены вообще. Я нашел этот факт на панели управления службами удаленного сервера.
Я пробовал код
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); process.Exited += new EventHandler(OnExited);
Это не полезно. Я слышал некоторые трюки, чтобы управлять потоком, передавая параметры в основной поток, а затем устанавливал что-то true
или false
т.д., Но просто не знал.
Если вы убьете этот процесс, а не закрываете его изящно (и это то, что вы делаете, когда закрываете окно консоли или нажимаете stop buttpn в отладчике), нет никаких шансов для запуска любого кода очистки. вы должны реализовать некоторый обработчик выхода, возможно, перехватывая ctrl-c press, а затем возвращайтесь из своих потоков, чтобы все объекты могли очистить себя.
Программа не будет работать, пока все запущенные потоки не будут остановлены.
Замените while (true)
в коде потока while (!stopThread.WaitOne(10, false))
где stopThread
- это WaitHandle
например ManualResetEvent
.
Затем, когда приложение выключится, Set
событие и дождитесь завершения потока.
Также обратите внимание, что некоторые сторонние фреймворки зависят от того, что Dispose
на их объекте, потому что им нужно управлять временем жизни некоторых отдельных потоков, которые они породили. Fe прочитал VoiceElements document
и посмотрел, как они вызывают Disconnect
и Dispose
на ChannelResource
которые у них есть из GetChannel()
. Пожалуйста, обратитесь к поставщику, когда и где вам нужно самостоятельно выпустить используемые ресурсы.
while (true) { ThreadEvent.WaitOne(waitingTime, false);
Я просто опущен в вопросе.
WaitHanle.WaitAny
и дождитесь, пока не будет установлено одно из событий, затем действуйте соответствующим образом.
TelephonyServer.GetChannel
что-то пропускает, либо приборная панель управления службами просто еще не обнаружила, что консольное приложение больше не подключено. Мы не можем проанализировать эту проблему на основании предоставленной информации.processExit
вProcessEachChannel
с помощью лямбды, которая правильно удаляет объект.