متى يجب استخدام كتل "باستخدام" في C #؟ [مكرر

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

  •  05-09-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

هل هناك حالات معينة يجب أن أستخدمها (أم لا؟) "باستخدام" كتل:

using(SomeType t = new SomeType()){
    ...
}
هل كانت مفيدة؟

المحلول

عندما SomeType تنفذ الطبقة IDisposable.

نصائح أخرى

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

إذا تركت كائن الملف، ونسيت استدعاء ملف. كلاوس () لن يتم تنظيفه حتى يتم تشغيل جامع القمامة (GC) وعملنا لا يزال لا يزال يستخدم كائن الملف. عندما يترك جامع القمامة يتم ترك وقت تشغيل اللغة الشائعة (CLR) لاتخاذ قرار. إذا لم يتم تشغيل GC لفترة طويلة بعد الانتهاء من الملف، فيمكن أن يبقى الملف مفتوحا لفترة طويلة. يمكن أن يشكل ذلك مشكلة كبيرة إذا كان هناك العديد من كائنات الملفات، أو إذا كان هناك شيء ما يريد فتح ملف، ولكن لا يمكن ذلك لأن كائن الملف الذي تركته لا يزال معلقا.

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

لحل هذه المشكلة، قدم C # الكلمة الأساسية "باستخدام". يمكنك وضع كلمة الكلمة الأساسية "باستخدام" حيث يمكنك الكائن الجديد، وهذا يضمن أن يتم استدعاء التخلص منها لك. يضمن أن يتم استدعاء التخلص من كل ما يحدث ... حتى لو كان هناك استثناء يتم إلقاؤه داخل جسم البيان باستخدام.

لذلك، يجب عليك استخدام "استخدام" عندما تريد التأكد من أن كائن يخصص الموارد سيتم تنظيفها.


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


الكائنات الشائعة التي تحتاج إلى استخدامها هي: الملفات واتصالات قاعدة البيانات والكائنات الرسومات مثل القلم والفرشاة.


في بعض الأحيان يتم استخدامه أيضا عندما تريد أن تحدث عمليا معا. على سبيل المثال، إذا كنت ترغب في كتابة عبارة سجل عند إدخال كتلة من التعليمات البرمجية وعند الخروج، يمكنك كتابة فئة سجل يمكنك استخدامها مثل هذا:

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

يمكن إجراء منشئ لفئة السجل لتدوين الرسالة، ويمكن أن تكتب طريقة التخلص منها أيضا. قم بتطبيق النهائي (~ LOG) لتأكيد ما إذا كانت طريقة التخلص منها لا يتم استدعاؤها لضمان تذكر "استخدام" حول "السجل الجديد".

يستخدم using كلما كان النوع ينفذ IDisposable, ، ما لم تكن سوف تلتفها في try/catch كتلة على أي حال، ثم قد تكون كذلك (اعتمادا على ما تبدو تفضل) استخدام finally منع.

أرى الكثير من الإجابات الأخرى المشار إليها عندك ينبغي عند using بيان. أريد أن أعالج متى يجب على وجه التحديد ليس عند using بيان:

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

الآن، لا تزال تريد أن تكون بالتأكيد أن هذه الكائنات يتم التخلص منها، لذلك لا تزال تريد using بيان في مكان ما. فقط لا تتضمنها في الطريقة التي يتم فيها إنشاء الكائن بالفعل. بدلا من ذلك، يمكنك التفاف وظيفة استدعاء نفسها في using بيان.

عندما تنفذ في وقت أخفي.

هذا هو دليل لك المطور الذي يستخدمه سنة موارد غير مدارة التي تحتاج إلى تنظيفها.

مثال:

        using(SqlConnection MyConnection = new SqlConnection("Connection string"))
        {
            MyConnection.Open();

            //...

            // 1. SQLConnection is a type that implements IDisposable
            // 2. So you can use MyConnection in a using statement
            // 3. When using block finishes, it calls Dispose method of 
            // SqlConnection class
            // 4. In this case, it will probably close the connection to 
            // the database and dispose MyConnection object

        }

يمكنك إنشاء الكائنات الخاصة بك التي تنفذ ناهتة:

public class MyOwnObjectThatImplementsIDisposable : IDisposable
{

    //... some code

    public void Dispose()
    {
        // Put here the code you want to be executed when the
        // using statement finish.
    }
}

لذلك يمكنك استخدام كائن من MyOwnObjectThanimesIrsidisposerable في بيان باستخدام:

        using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable)
        {

            // When the statement finishes, it calls the 
            // code you´ve writed in Dispose method
            // of MyOwnObjectThatImplementsIDisposable class
        }

أتمنى أن يساعدك هذا

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

مثيل محدد واحد يجب أن تكون حذرا باستخدام using كتلة هو مع عميل خدمة WCF.

كما لاحظ في هذه المادة MSDN, ، التفاف عميل WCF (الذي ينفذ IDisposable) في using يمكن أن يقنع Block أي أخطاء تؤدي إلى ترك العميل في حالة مخيبة (مثل مشكلة المهلة أو الاتصال). قصة قصيرة قصيرة، متى Dispose() يسمى، العميل Close() طريقة الحرائق، ولكن رميات والخطأ لأنه في حالة مخيبة. الاستثناء الأصلي ثم ملثم من الاستثناء الثاني. ليست جيدة.

هناك حلول مختلفة هناك، بما في ذلك واحدة في المادة MSDN نفسها. يمكن العثور على الآخرين في iservicegoriented. و blog.davidbarret.net..

أنا أفضل الطريقة الأخيرة، نفسي.

إذا كنت تريد قاعدة ملخص. في أي وقت كائن يستخدم Irisaberable حيث لن يكون لديك قبض واستخدام استخدام. باستخدام، أساسا، هو هذا النمط:

try
{
  //instantiate and use object
}
finally
{
  //dispose object
}

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

القاعدة الأساسية هي: * استخدم استخدام العبارة عندما تنفذ الكائنات واجهة غير قابلية.

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

من المهم للغاية أن تكون جميع الموارد التي لم تعد قيد الاستخدام مجانية في أقرب وقت ممكن.

لمزيد من المعلومات حول هذا الموضوع فقط قم بزيارة هذا الرابط: مايكروسوفت

ربما تجدر الإشارة إلى أن السبب الأساسي لإضافة "استخدام" LO C # هو التالي: يمكن أن تكون بعض الموارد شحيحة بما يكفي لأنها لا معنى لها الانتظار للحصول على GC للاتصال. على سبيل المثال، اتصالات DB. إذا كنت تستخدم TRY / CATCK / أخيرا، فلن ينتهي بك الأمر باتصال تتدلى، ولكن سيتم ترك الاتصال معلقا حتى لا يرتبط GC ويمكن أن يستغرق الأمر بعض الوقت (إذا كنت لا تغلقه صراحة). إذا كنت تستخدم "استخدام" (إسمح التورية)، فستحرر الاتصال على الفور حتى لو نسيت إغلاقه وحتى إذا حدث بعض الاستثناءات داخل كتلة الاستخدام.
سبب آخر، كما يذكر المنشور السابق، هو أن المبرمجين لا يستخدمون دائما في النهاية لتنظيف. إذا لم تستخدم أخيرا في حالة الاستثناء، فأنت في نهاية المطاف مع موارد تسرب ...

حالة واحدة هي عندما تريد أن تفعل شيئا في بداية كتلة التعليمات البرمجية، ثم التراجع عنها في نهاية الكتلة، دون قيد أو شرط (حتى لو كان هناك رمي).

سيقوم المحبط في الطبقة المتاح التي تبنيها (والاتصال داخل الاستخدام) تنفيذ الإجراء، ثم طريقة التخلص من التخلص من التراجع عن هذا الإجراء. هذا هو عادة كيف يمكنني استخدامه.

وقد ذكر أشخاص آخرون عن "ناهض" بالفعل.

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

لذلك في المقتطف التالي،

using (SomeType t = new SomeType()){
    throw new Exception("thrown within using");
}

throw new Exception("thrown within using"); لا ينبغي تجاهلها.

أود إضافة هذا استخدام using() بيان إذا كان هناك شيء ينفذ IDispose وأيضا إذا كان هذا الشيء الذي تريد التخلص منه من الموارد غير المدبرة مثل اتصالات قاعدة البيانات ومقابض الملفات.

إذا كان كائن طبيعي مع القول List<T>, ، حيث تي مثل Customer الكائن الذي يحمل الأسماء والعنوان، ثم لا تحتاج إلى ذلك. جامع القمامة ذكي بما يكفي لإدارة هذا لك. لكن جامع القمامة لن يرجع الاتصالات إلى تجمع الاتصال أو مقابض الملفات الوثيقة.

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