هل stream.dispos دائما استدعاء stream.close (و stream.flush)

StackOverflow https://stackoverflow.com/questions/911408

  •  06-09-2019
  •  | 
  •  

سؤال

إذا كان لدي الوضع التالي:

StreamWriter MySW = null;
try
{
   Stream MyStream = new FileStream("asdf.txt");
   MySW = new StreamWriter(MyStream);
   MySW.Write("blah");
}
finally
{
   if (MySW != null)
   {
      MySW.Flush();
      MySW.Close();
      MySW.Dispose();
   }
}

هل يمكنني فقط الاتصال MySW.Dispose() وتخطي الإغلاق على الرغم من توفيره؟ هل هناك أي جرائم تيار لا تعمل كما هو متوقع (مثل CryptoStream)؟

إذا لم يكن كذلك، فهذا هو رمز سيئة فقط:

using (StreamWriter MySW = new StreamWriter(MyStream))
{
   MySW.Write("Blah");
}
هل كانت مفيدة؟

المحلول

هل يمكنني فقط استدعاء MySw.Dispose () وتخطي الإغلاق على الرغم من توفيره؟

نعم، هذا ما هو عليه.

هل هناك أي تطبيقات دفق لا تعمل كما هو متوقع (مثل CryptoStream)؟

من الآمن افتراض أنه إذا كان كائن ينفذ IDisposable, ، سوف تتخلص من نفسه بشكل صحيح.

إذا لم يكن كذلك، فسيكون ذلك خطأ.

إذا لم يكن كذلك، فهذا هو رمز سيئة فقط:

لا، هذا الكود هو الطريقة الموصى بها للتعامل مع الكائنات التي تنفذ IDisposable.

معلومات أكثر ممتازة في الإجابة المقبولة على إغلاق والتخلص - التي تتصل بها؟

نصائح أخرى

لقد استخدمت العاكس ووجدت ذلك System.IO.Stream.Dispose يشبه هذا:

public void Dispose()
{
    this.Close();
}

كما ذكر Daniel Bruckner، والتخلص والإغلاق بشكل فعال نفس الشيء.

ومع ذلك، لا يدعو الدفق فلوش () عند التخلص منه / مغلقا. FileStream (وأنا أفترض أي دفق آخر مع آلية التخزين المؤقت) هل يدعو الدفاحة () عند التخلص منها.

إذا كنت توسع نطاقا، أو مخصصات موضة وما إلى ذلك، فستحتاج إلى تنفيذ مكالمة للتدفئة () عند التخلص منها / مغلق إذا كان ذلك ضروريا.

كلا StreamWriter.Dispose () و Stream.Dispose () حرر جميع الموارد التي تحتفظ بها الكائنات. كلاهما يغلق دفق الأساس.

رمز المصدر من Stream.Dispose () (لاحظ أن هذه تفاصيل التنفيذ حتى لا تعتمد عليها):

public void Dispose()
{
    this.Close();
}

streamwriter.disposite () (كما هو الحال مع Stream.Dispose ()):

protected override void Dispose(bool disposing)
{
    try
    {
        // Not relevant things
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {
            try
            {
                if (disposing)
                {
                    this.stream.Close();
                }
            }
            finally
            {
                // Not relevant things
            }
        }
    }
}

ومع ذلك، عادة ما أقوم ضمنيا بإغلاق تدفقات / Streamwraters قبل التخلص منها - أعتقد أنها تبدو نظافة.

سيحاول جميع الجداول القياسية (FileStream، CryptoStream) تدفق عند إغلاق / التخلص منها. أعتقد أنه يمكنك الاعتماد عليه من أجل أي تطبيقات Microsoft Stream.

نتيجة لذلك، يمكن إغلاق / متابعة رمي استثناء إذا فشل الدفاحة.

في الواقع IIRC، كان هناك خطأ في .NET 1.0 تنفيذ FileStream في أنه سيفشل في إصدار مقبض الملفات إذا ارمي التدفق استثناء. تم إصلاح ذلك في .NET 1.1 عن طريق إضافة تجربة تجربة / أخيرا إلى طريقة التخلص (منطقية).

بالنسبة للأشياء التي تحتاج إلى إغلاق يدويا، يجب بذل كل جهد ممكن لإنشاء الكائن في كتلة باستخدام.

//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
   //Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream' 

وبهذه الطريقة، لا يمكن للمرء عدم الوصول بشكل غير صحيح "دفق" خارج سياق جملة الاستخدام ويتم إغلاق الملف دائما.

نظرت في مصدر .NET لفصل الدفق، كان لها ما يلي تشير إلى نعم يمكنك ...

    // Stream used to require that all cleanup logic went into Close(),
    // which was thought up before we invented IDisposable.  However, we 
    // need to follow the IDisposable pattern so that users can write
    // sensible subclasses without needing to inspect all their base
    // classes, and without worrying about version brittleness, from a
    // base class switching to the Dispose pattern.  We're moving 
    // Stream to the Dispose(bool) pattern - that's where all subclasses
    // should put their cleanup starting in V2. 
    public virtual void Close() 
    {
        Dispose(true); 
        GC.SuppressFinalize(this);
    }

    public void Dispose() 
    {
        Close(); 
    } 

Stream.Close يتم تنفيذها بواسطة مكالمة Stream.Dispose أو العكس - لذلك الطرق معادلة. Stream.Close موجود فقط لأن إغلاق دفق يبدو طبيعيا أكثر من التخلص من دفق.

إلى جانب ذلك يجب أن تحاول تجنب المكالمات الصريحة لهذه الطرق واستخدام using بيان بدلا من ذلك من أجل الحصول على معالجة الاستثناء الصحيح مجانا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top