Пожалуйста, рассмотрите этот довольно простой сценарий. У меня есть два консольных приложения .NET 4.0/С#. Назовем их имена «Launcher» и «SocketApp».
Launcher не делает ничего, кроме запуска SocketApp при определенных обстоятельствах. Это делается с помощью метода Process.Start(). SocketApp работает какое-то время, и через некоторое время его цикл Main() завершается, и процесс умирает. И процесс остается мертвым, пока Launcher не запустит его снова. (Ни при каких условиях не будет запущено несколько экземпляров SocketApp). И так цикл идет. Это работает нормально в течение нескольких дней.
Но иногда SocketApp не запускается. Он выдает исключение, когда канал удаленного взаимодействия пытается прослушивать сокет. Исключение создается глубоко во внутреннем коде Remoting, точнее, при вызове Bind(). Причина сбоя вызова привязки заключается в том, что сокет каким-то образом никогда не освобождался при ПРЕДЫДУЩЕМ успешном запуске SocketApp. Я знаю, что это так, потому что если я гарантирую, что SocketApp закрыт, и я делаю netstat -n, я вижу, что порт, к которому я хочу Bind(), привязан. Он находится в постоянном состоянии CLOSE_WAIT. И он просто остается в этом состоянии CLOSE_WAIT навсегда.
Единственный способ заставить Windows освободить этот сокет — это (и это становится странным) закрыть приложение Launcher. С чего бы это? Launcher работает в своем собственном процессе и вообще не использует сокеты. Его единственная цель - запустить SocketApp. Так почему же закрытие Launcher освобождает сокет, который использует только SocketApp? Может быть, это потому, что я не вызываю Dispose() для объекта Process из Launcher? Этот сбой появляется так редко, что требуется несколько дней, чтобы определить, эффективно ли какое-либо конкретное исправление. Что-нибудь еще, на что я должен смотреть?
Декстер