我有一个控制台应用程序,通过tcp / ip连接远程服务器上的第三方Windows服务。
呼叫层次结构喜欢:
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
等,但是没有任何线索。
答案 0 :(得分:1)
在所有正在运行的线程都停止之前,程序不会退出。
将线索代码中的while (true)
替换为while (!stopThread.WaitOne(10, false))
,其中stopThread
为WaitHandle
ManualResetEvent
。
然后,当应用程序关闭时,Set
该事件并等待线程退出。
另请注意,某些第三方框架依赖于在其对象上调用Dispose
,因为它们需要管理它们生成的某些单独线程的生命周期。 F.E.阅读VoiceElements document
,看看他们如何通过Disconnect
从Dispose
调用ChannelResource
和GetChannel()
。请在需要的时间和地点与提供商联系,自行释放使用过的资源。
答案 1 :(得分:0)
如果您终止进程,而不是正常关闭它(这就是关闭控制台窗口或在调试器中按下stop buttpn时所执行的操作),则无法运行任何清理代码。 你必须实现一些退出处理程序,可能会捕获一个ctrl-c按,然后从你的线程返回,这样所有对象都可以干净地自行处理。