मैं एक स्थिति है जहाँ कचरा संग्रहण एक यूनिट टेस्ट बनाम एक कंसोल आवेदन की Main
विधि में लिखा के रूप में लिखा चल रहा एक ही कोड के बीच अलग-अलग ढंग से व्यवहार किया जा रहा है भर में ठोकर खाई है । मैं इस अंतर के पीछे कारण सोच रहा हूँ।विभिन्न कूड़ा संग्रह व्यवहार
इस स्थिति में, एक सह कार्यकर्ता और मैं कचरा संग्रहण पर एक घटना हैंडलर पंजीकृत करने के प्रभाव पर असहमति में थे। मैंने सोचा कि एक प्रदर्शन को highly rated SO answer पर एक लिंक भेजने से बेहतर प्रदर्शन किया जाएगा। जैसे मैंने यूनिट टेस्ट के रूप में एक सरल प्रदर्शन लिखा था।
मेरी यूनिट टेस्ट ने चीजों को दिखाया जैसा मैंने कहा था कि उन्हें चाहिए। हालांकि, मेरे सहकर्मी ने एक कंसोल एप्लिकेशन लिखा जो दिखाता है कि चीजें अपने तरीके से काम कर रही हैं, जिसका मतलब है कि जीसी नहीं हो रहा था क्योंकि मुझे स्थानीय वस्तुओं पर Main
विधि में अपेक्षित था। मैं कंसोल एप्लिकेशन प्रोजेक्ट की Main
विधि में अपने परीक्षण से कोड को स्थानांतरित करके बस देखे गए व्यवहार को पुन: उत्पन्न करने में सक्षम था।
मैं क्या जानना चाहता हूं कि जीसी कंसोल एप्लिकेशन की Main
विधि में चलते समय वस्तुओं को इकट्ठा करने की प्रतीत क्यों नहीं कर रहा है। विधियों को निकालने से GC.Collect
पर कॉल और दायरे से बाहर निकलने वाली वस्तु विभिन्न तरीकों से हुई, अपेक्षित व्यवहार बहाल किया गया था।
ये वे वस्तुएं हैं जिनका उपयोग मैंने अपने परीक्षण को परिभाषित करने के लिए किया था। एक घटना के साथ बस एक वस्तु है और एक वस्तु एक घटना हैंडलर के लिए उपयुक्त विधि प्रदान करने वाला एक वस्तु है। दोनों में ग्लोबल वैरिएबल सेट करने वाले फाइनलर्स हैं ताकि आप बता सकें कि उन्हें कब एकत्र किया गया है।
[Test]
public void TestReference()
{
{
HandlingObject subscriber = new HandlingObject();
{
{
EventedObject publisher = new EventedObject();
publisher.DoIt += subscriber.Yeah;
}
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Thread.MemoryBarrier();
Assert.That(Log, Is.EqualTo(EventedObjectDisposed));
}
//Assertion needed for foo reference, else optimization causes it to already be collected.
Assert.IsNotNull(subscriber);
}
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Thread.MemoryBarrier();
Assert.That(Log, Is.EqualTo(HandlingObjectDisposed));
}
मैं एक नया कंसोल आवेदन की Main
विधि करने के लिए ऊपर शरीर चिपकाया, और Trace.Assert
आमंत्रण को Assert
कॉल परिवर्तित:
private static string Log;
public const string EventedObjectDisposed = "EventedObject disposed";
public const string HandlingObjectDisposed = "HandlingObject disposed";
private class EventedObject
{
public event Action DoIt;
~EventedObject()
{
Log = EventedObjectDisposed;
}
protected virtual void OnDoIt()
{
Action handler = DoIt;
if (handler != null) handler();
}
}
private class HandlingObject
{
~HandlingObject()
{
Log = HandlingObjectDisposed;
}
public void Yeah()
{
}
}
यह मेरा परीक्षण (NUnit) है, जो गुजरता है। दोनों समानता दावा विफल हो जाते हैं तो विफल हो जाते हैं। परिणामी मुख्य विधि का कोड here है यदि आप इसे चाहते हैं।
मुझे पता है कि जब जीसी होता है तो उसे गैर-निर्धारिती के रूप में माना जाना चाहिए और आमतौर पर जब कोई ऐसा होता है तो एक आवेदन स्वयं से संबंधित नहीं होना चाहिए। सभी मामलों में कोड रिलीज़ मोड में संकलित किया गया था और .NET 4.5 को लक्षित किया गया था।
संपादित करें: अन्य बातें मैंने कोशिश की
- परीक्षा पद्धति
static
बनाने के बाद से NUnit कि समर्थन करता है; परीक्षण अभी भी काम किया। - मैं भी कार्यक्रम पर एक उदाहरण विधि में निकालने पूरे मुख्य विधि और कहा कि फोन करने की कोशिश की। दोनों आवेदक अभी भी असफल रहे।
[STAThread]
या[MTAThread]
के साथ this के मामले में एक फर्क पड़ता है। दोनों अभी भी विफल रहा है पाता है।- @ मू-रस के सुझावों के आधार पर:
- मैं कंसोल अनुप्रयोग के लिए NUnit संदर्भित ताकि मैं इस्तेमाल कर सकते हैं NUnit का दावा है, वे विफल रहे।
- मैंने टेस्ट, टेस्ट क्लास,
Main
विधि, औरMain
विधि स्थिर दोनों कक्षाओं की दृश्यता में विभिन्न परिवर्तनों की कोशिश की। कोई परिवर्तन नहीं होता है। - मैंने टेस्ट क्लास स्थिर और
Main
विधि स्थिर युक्त कक्षा बनाने की कोशिश की। कोई परिवर्तन नहीं होता है।
जब आप 'जीसी.कोलेक्ट()' का उपयोग अपने डिफ़ॉल्ट पैरामीटर के साथ करते हैं और पीढ़ी निर्दिष्ट नहीं करते हैं तो इसका क्या परिणाम होता है? –
@ म्यू-रस परीक्षण अभी भी गुजरता है, कंसोल एप्लिकेशन का दावा अभी भी असफल हो जाता है, कंसोल से विधियों को निकालने के लिए आवेदन अभी भी सफल होने के लिए आवेषण का कारण बनता है। – vossad01
मुझे आश्चर्य है कि अंतर इस तथ्य के कारण है कि 'मुख्य' एक स्थिर वर्ग के भीतर है ... मुझे यकीन नहीं है, लेकिन इसके अलावा और 'ट्रेस' बनाम 'एसेर्ट' के व्यवहार के अलावा मैं विचारों से बाहर हूं। क्या आपने परीक्षण को स्थिर आंकड़ों के भीतर से चलाने का प्रयास किया है? –