【问题标题】:Does it make sense to have using statement inside class constructor? [duplicate]在类构造函数中使用 using 语句是否有意义? [复制]
【发布时间】:2020-04-22 16:47:20
【问题描述】:

我的意思是使用下面的语句,在我的类的构造函数中使用FileSystemWatcher 实例,在这样的类构造函数中使用using 语句是否有意义,或者它必须在没有using 语句的构造函数中?

public partial class MyService : ServiceBase
        {
            FileInfo file;
            StreamWriter writer;
            FileSystemWatcher watcher1;
            FileSystemWatcher watcher2;
            FileSystemWatcher watcher3;

            public MyService()
            {
                InitializeComponent();

                file = new FileInfo(@"D:\LOGS\Log.txt");
                writer = file.CreateText();
    //I mean this using
                using (watcher1 = new FileSystemWatcher(@"C:\"))
                {
                    watcher1.Created += OnChanged;
                    watcher1.Deleted += OnChanged;
                    watcher1.Renamed += OnRenamed;
                    watcher1.Changed += OnChanged;
                    watcher1.EnableRaisingEvents = true;
                }
    //I mean this using
                using (watcher3 = new FileSystemWatcher(@"C:\Users"))
                {
                    watcher3.IncludeSubdirectories = true;
                    watcher3.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
                                            NotifyFilters.FileName | NotifyFilters.DirectoryName;
                    watcher3.Created += OnChanged;
                    watcher3.Deleted += OnChanged;
                    watcher3.Renamed += OnRenamed;
                    watcher3.Changed += OnChanged;
                    watcher3.Filter = "*.*";
                    watcher3.EnableRaisingEvents = true;
                }
     //I mean this using
                using (watcher2 = new FileSystemWatcher(@"D:\"))
                {
                    watcher2.IncludeSubdirectories = true;
                    watcher2.Created += OnChanged;
                    watcher2.Deleted += OnChanged;
                    watcher2.Renamed += OnRenamed;
                    watcher2.Changed += OnChanged;
                    watcher2.EnableRaisingEvents = true;
                }
            }

【问题讨论】:

  • 您是否在构造函数之外使用它们以及如何使用它们?
  • 是的,观察者实例可以在构造函数之外使用,问题是构造函数内部是否需要 using 语句。
  • 没有。 using 将立即处理对象。当您确定不再需要它们时,您需要保留引用并在以后明确地处置对象。请参阅标记的重复项以获取答案。

标签: c# constructor dispose using-statement


【解决方案1】:

您应该在服务运行时保持所有这些 FileSysteWatcher 实例不被释放。但是您也应该在处置服务时处置所有资源。所以最好的解决方案是通过你的服务实现IDisposable,并在Dispose方法中处理所有资源。

public partial class MyService : ServiceBase
{
    FileSystemWatcher watcher1;
    FileSystemWatcher watcher2;
    FileSystemWatcher watcher3;

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            watcher1?.Dispose();
            watcher2?.Dispose();
            watcher3?.Dispose();
        }

        base.Dispose(disposing);
    }
}

还考虑将初始化逻辑移至OnStart 服务方法。或者至少在服务启动时启用观察者并在服务停止时禁用它们:

    protected override void OnStart(string[] args)
    {
        base.OnStart(args);

        watcher1.EnableRaisingEvents = true;
        watcher2.EnableRaisingEvents = true;
        watcher3.EnableRaisingEvents = true;
    }

    protected override void OnStop()
    {
        base.OnStop();

        watcher1.EnableRaisingEvents = false;
        watcher2.EnableRaisingEvents = false;
        watcher3.EnableRaisingEvents = false;
    }

注意:不要忘记同时处理writer

【讨论】:

  • 你能看到我最后的答案吗?
【解决方案2】:

谢尔盖的回答已经很好了,我只是想补充一些理论。

一般来说,你应该只使用在 using 中声明的变量,比如

 using(var watcher = new ...)` 

因为变量在使用括号的末尾被销毁/处置。所以永远不要在字段或属性上使用它。 Using 只是一个简写,在最后做一个 Dispose ,也在引发异常的情况下。如果您不想在同一方法中创建和销毁变量,则不能使用“使用”。

通过您的方法,观察者被处置/销毁,但未设置为空。所以它会导致奇怪的行为。为了避免这种情况,using 中的变量不应该存在于 using 之外,它应该超出范围,这就是为什么你在 using 范围内声明变量的原因。

一次性用品有两种模式。您可以将它与“使用”一起使用以在同一方法中创建/销毁它,或者将其包含在一次性类中。您在一个类中创建它,并在处置拥有的类时处置它。在拥有类上,您再次应用相同的规则,也许拥有类可以与 using 块一起使用。 Sergeys 实现假定,您的外部类派生自已经实现 IDisposable 的类。

【讨论】:

    猜你喜欢
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多