【问题标题】:How do I correctly exit/stop/dispose a console application in C#如何在 C# 中正确退出/停止/处置控制台应用程序
【发布时间】:2013-03-25 16:16:48
【问题描述】:

我注意到在我的任务管理器中我有这个应用程序的多个副本 - 虽然不占用任何 CPU 资源。

我知道我一定做错了什么,所以我问集体......

这是经过消毒的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace AnalyticsAggregator
{
class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        try
        {
            bool onlyInstance = false;
            Mutex mutex = new Mutex(true, "AnalyticsAggregator", out onlyInstance);
            if (!onlyInstance)
            {
                return;
            }

                            "Do stuff with the database"


            GC.KeepAlive(mutex);
        }
        catch (Exception e)
        {

                EventLog eventlog = new EventLog("Application");
                eventlog.Source = "AnalyticsAggregator";
                eventlog.WriteEntry(e.Message, EventLogEntryType.Error);
            }
        }
    }
}
}

我有其他不是互斥体/单例的控制台应用程序表现出相同的行为,我做错了什么?我假设某种类型的处置......

谢谢

【问题讨论】:

  • 你里面为什么有GC.KeepAlive(mutex)
  • 我将您的代码复制并粘贴到 Visual Studio 中,并将 "Do Stuff" 行替换为长 Thread.Sleep(100000)。它按预期工作,只有一个应用程序实例正在运行。您能否发布可以重现问题的代码以及有关您的环境的更多信息?
  • 我见过然后使用的例子有 GC.KeepAlive(mutex);这是错的吗?
  • GC.KeepAlive(object) (msdn.microsoft.com/en-us/library/…) 的 MSDN 文档中,看起来只有在调用可能挂在指定对象上的非托管代码时才应该使用它。您是否在“Do stuff with the database”代码中使用了任何 COM 代码或非托管 DLL?
  • @feralin 不,只是 TableAdapter 调用。我们目前使用 TableAdapters 作为我们的 DAL。

标签: c# console-application


【解决方案1】:

控制台应用程序将在完成后终止,通常是在它运行到其 Main 入口点方法的末尾时,但您必须小心摆脱您可能一直在管理的任何挥之不去的资源,因为它们可以保持底层进程活着。

您可以使用Environment.ExitApplication.Exit 显式退出,尽管根据我的经验后者是基于表单的(与清除消息泵和关闭窗口等有关)。

底线是一定要做好家务。

【讨论】:

  • 挥之不去的资源——比如数据库连接?我现在正在调查。
  • @BuddyMurphy 正是——类似的东西;确保在 IDisposables 上调用 Dispose。
【解决方案2】:

您可以尝试围绕Mutex 的使用添加using 语句。示例:

using (Mutex mutex = new Mutex(true, "AnalyticsAggregator", out onlyInstance))
{
    if (!onlyInstance) return;
    ... database stuff ...
}

当大括号内的代码以任何方式(正常执行或异常)退出时,这将自动处理 Mutex 实例。

【讨论】:

    【解决方案3】:
    Application.Exit();
    

    这是标准方法,但除非您希望通过用户输入退出应用程序(例如,您想退出应用程序 (y/n)?),否则关闭控制台就足够了。

    【讨论】:

    • @feralin 我认为你是对的,数据库连接没有被正确释放。
    • 那么 application.exit 不会在这里起到一个全部作用吗?关于数据库,连接将一直挂起,直到数据库服务器对其计时,但这不是我想的问题。无论如何,如果 application.exit 由于某种原因不起作用,Environment.Exit(0) 是更极端的形式,有点像 kill 命令。
    猜你喜欢
    • 1970-01-01
    • 2011-02-01
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多