退出Windows控制台应用程序以清理资源

时间:2014-08-18 18:12:01

标签: c# .net multithreading

我有一个控制台应用程序,通过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);

没用。我听到一些技巧来管理线程,方法是将参数传递给主线程,然后设置一些truefalse等,但是没有任何线索。

2 个答案:

答案 0 :(得分:1)

在所有正在运行的线程都停止之前,程序不会退出。

将线索代码中的while (true)替换为while (!stopThread.WaitOne(10, false)),其中stopThreadWaitHandle ManualResetEvent

然后,当应用程序关闭时,Set该事件并等待线程退出。

另请注意,某些第三方框架依赖于在其对象上调用Dispose,因为它们需要管理它们生成的某些单独线程的生命周期。 F.E.阅读VoiceElements document,看看他们如何通过DisconnectDispose调用ChannelResourceGetChannel()。请在需要的时间和地点与提供商联系,自行释放使用过的资源。

答案 1 :(得分:0)

如果您终止进程,而不是正常关闭它(这就是关闭控制台窗口或在调试器中按下stop buttpn时所执行的操作),则无法运行任何清理代码。 你必须实现一些退出处理程序,可能会捕获一个ctrl-c按,然后从你的线程返回,这样所有对象都可以干净地自行处理。