سؤال

لدي هذا الرمز الذي يحفظ ملف PDF.

FileStream fs = new FileStream(SaveLocation, FileMode.Create);
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
fs.Flush();
fs.Close();

أنه يعمل بشكل جيد. ومع ذلك ، فإنه في بعض الأحيان لا يطلق القفل على الفور ويؤدي ذلك إلى استثناءات قفل الملف مع وظائف يتم تشغيلها بعد هذا التشغيل.

هل هناك طريقة مثالية لإصدار قفل الملف تماما بعد ال fs.close ()

هل كانت مفيدة؟

المحلول

هذا هو المثل الأعلى:

using (var fs = new FileStream(SaveLocation, FileMode.Create))
{
    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}

وهو ما يعادل:

FileStream fs =  null;
try
{
    fs = new FileStream(SaveLocation, FileMode.Create);
    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
finally
{
    if (fs != null)
    {
        ((IDisposable)fs).Dispose();
    }
}

ال استخدام أن تكون أكثر قابلية للقراءة.


تحديث:

Aron ، الآن بعد أن أفكر

File.WriteAllBytes(SaveLocation, result.DocumentBytes);

يبدو أجمل للعين من المثالية :-)

نصائح أخرى

لقد رأينا هذه المشكلة نفسها في الإنتاج من خلال بيان استخدام () لفها.

أحد أفضل الجناة هنا هو برنامج مكافحة الفيروسات الذي يمكن أن يتسلل بعد إغلاق الملف ، والاستيلاء عليه للتحقق من أنه لا يحتوي على فيروس قبل إطلاقه.

ولكن حتى مع إخراج جميع البرامج المضادة للفيروسات من هذا المزيج ، في أنظمة تحميل عالية جدًا مع ملفات مخزنة على أسهم الشبكة ، ما زلنا شاهدت المشكلة من حين لآخر. A ، السعال ، الخيط القصير. إذا كان لدى شخص ما حل أفضل أحب أن أسمعه!

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

using (FileStream fs = new FileStream(SaveLocation, FileMode.Create))
{
  fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);  
}

إذا كانت الوظائف التي يتم تشغيلها بعد هذا التطبيق جزءًا من نفس التطبيق ، فقد يكون النهج الأفضل هو فتح الملف للقراءة/الكتابة في بداية العملية بأكملها ، ثم تمرير الملف إلى كل وظيفة دون إغلاقه حتى نهاية العملية. بعد ذلك ، لن يكون من الضروري أن يمنع التطبيق في انتظار إكمال عملية IO.

لقد نجح هذا بالنسبة لي عند استخدام .flush () اضطررت إلى إضافة إغلاق داخل البيان باستخدام.

 using (var imageFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))
 {
     imageFile.Write(bytes, 0, bytes.Length);
     imageFile.Flush();
     imageFile.Close();
  }

لقد واجهت نفس المشكلة عندما أغلقت FileStream وفتحت الملف فورًا في فئة أخرى. لم يكن البيان باستخدام حل منذ أن تم إنشاء filestream في مكان آخر وتخزينه في قائمة. لم يكن مسح القائمة كافيًا.

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

GC.Collect();

مباشرة بعد إغلاق الدفق. هذا عمل بالنسبة لي.

أعتقد أن حلول إيان ميرسر لوضع الخيط في النوم قد يكون لها نفس التأثير ، مما يمنح GC وقتًا لتحرير الموارد.

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