सी # में डुप्लिकेट त्रुटि हैंडलिंग कोड को कम करना?

वोट
32

मैं जिस तरह से अपवाद हैंडलिंग काम करता है के साथ पूरी तरह से खुश कभी नहीं किया गया है, वहाँ एक बहुत अपवाद और कोशिश / पकड़ तालिका में लाता है (स्टैक, आदि), लेकिन यह प्रक्रिया में OO मॉडल का एक बहुत तोड़ने के लिए लगता है।

वैसे भी, यहाँ समस्या है:

मान लीजिए कि आप कुछ वर्ग जो लपेटता या नेटवर्क फ़ाइल आईओ आपरेशन (जैसे पढ़ने और कहीं कुछ विशेष यूएनसी पथ पर कुछ फ़ाइल के लिए लिख) भी शामिल है करते हैं। विभिन्न कारणों के लिए आप उन आईओ कार्रवाई विफल नहीं करना चाहते, इसलिए यदि आप का पता लगाने कि वे आप उन्हें पुन: प्रयास असफल और आप उन्हें पुन: प्रयास रखने के लिए जब तक वे सफल हैं या आप एक समय समाप्ति तक पहुँचते हैं। मैं पहले से ही एक सुविधाजनक RetryTimer वर्ग जो मैं का दृष्टांत और, आदि पुनः के बीच मौजूदा धागा सोने और निर्धारित जब समय समाप्ति की अवधि बीत जाने के लिए उपयोग कर सकते हैं

समस्या आप इस वर्ग के कई तरीके में आईओ संचालन का एक समूह है, और आप कोशिश पकड़ / पुन: प्रयास करें तर्क में उनमें से प्रत्येक रैप करने के लिए की जरूरत है।

यहाँ एक उदाहरण कोड का टुकड़ा है:

RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
bool success = false;
while (!success)
{
    try
    {
        // do some file IO which may succeed or fail
        success = true;
    }
    catch (IOException e)
    {
        if (fileIORetryTimer.HasExceededRetryTimeout)
        {
            throw e;
        }
        fileIORetryTimer.SleepUntilNextRetry();
    }
}

तो, आप कक्षा में हर फ़ाइल आईओ ऑपरेशन के लिए इस कोड का सबसे डुप्लिकेट करने से बचने के हैं? मेरे समाधान गुमनाम प्रतिनिधि ब्लॉक और कक्षा में एक भी तरीका है जिसके प्रतिनिधि इसे करने के लिए पारित कर दिया ब्लॉक निष्पादित उपयोग करने के लिए किया गया था। यह मैं अन्य तरीकों में इस तरह काम करने की अनुमति दी:

this.RetryFileIO( delegate()
    {
        // some code block
    } );

मैं कुछ हद तक यह पसंद है, लेकिन यह एक बहुत होना बाकी है। मैं कैसे अन्य लोगों को इस तरह की समस्या का समाधान होगा सुनना चाहते हैं।

04/08/2008 को 20:21
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


4 जवाब

वोट
13

इस पहलू उन्मुख प्रोग्रामिंग पर एक नजर है करने के लिए एक उत्कृष्ट अवसर की तरह दिखता है। यहाँ पर एक अच्छा लेख है .NET में AOP । सामान्य विचार है कि आप पार कार्यात्मक चिंता (एक्स घंटे के लिए यानी पुन: प्रयास करें) एक अलग वर्ग में निकालने चाहते हैं और उसके बाद आप किसी भी तरीके कि रास्ते में उनके व्यवहार को संशोधित करने की जरूरत है कि व्याख्या चाहते हैं। यह इस प्रकार से (Int32 पर एक अच्छी विस्तार विधि के साथ) दिखाई दे सकता है

[RetryFor( 10.Hours() )]
public void DeleteArchive()
{
  //.. code to just delete the archive
}
05/08/2008 को 10:43
का स्रोत उपयोगकर्ता

वोट
4

बस सोच रहा है, क्या आप अपने विधि होना बाकी है महसूस करते हैं? आप एक साथ अनाम प्रतिनिधि बदल सकते .. नामित? प्रतिनिधि, की तरह कुछ

    public delegate void IoOperation(params string[] parameters);

    public void FileDeleteOperation(params string[] fileName)
    {
        File.Delete(fileName[0]);
    }

    public void FileCopyOperation(params string[] fileNames)
    {
        File.Copy(fileNames[0], fileNames[1]);
    }

    public void RetryFileIO(IoOperation operation, params string[] parameters)
    {
        RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
        bool success = false;
        while (!success)
        {
            try
            {
                operation(parameters);
                success = true;
            }
            catch (IOException e)
            {
                if (fileIORetryTimer.HasExceededRetryTimeout)
                {
                    throw;
                }
                fileIORetryTimer.SleepUntilNextRetry();
            }
        }
    }

    public void Foo()
    {
        this.RetryFileIO(FileDeleteOperation, "L:\file.to.delete" );
        this.RetryFileIO(FileCopyOperation, "L:\file.to.copy.source", "L:\file.to.copy.destination" );
    }
04/08/2008 को 21:07
का स्रोत उपयोगकर्ता

वोट
2

यहाँ है कि मैं क्या हाल ही में किया है। यह शायद कहीं और बेहतर किया गया है, लेकिन यह काफी साफ है और पुन: प्रयोज्य लगता है।

मैं एक उपयोगिता विधि है कि इस तरह दिखता है:

    public delegate void WorkMethod();

    static public void DoAndRetry(WorkMethod wm, int maxRetries)
    {
        int curRetries = 0;
        do
        {
            try
            {
                wm.Invoke();
                return;
            }
            catch (Exception e)
            {
                curRetries++;
                if (curRetries > maxRetries)
                {
                    throw new Exception("Maximum retries reached", e);
                }
            }
        } while (true);
    }

तो फिर अपने आवेदन में, मैं चीजों को स्वच्छ रखने के लिए सी # के Lamda अभिव्यक्ति सिंटैक्स का उपयोग करें:

Utility.DoAndRetry( () => ie.GoTo(url), 5);

यह मेरा प्रणाली को बुलाती है और 5 गुना तक पुनः प्रयास करता है। पांचवें प्रयास में मूल अपवाद एक पुनः प्रयास अपवाद के अंदर rethrown है।

13/09/2010 को 03:25
का स्रोत उपयोगकर्ता

वोट
2

तुम भी एक और अधिक OO दृष्टिकोण इस्तेमाल कर सकते हैं:

  • एक आधार वर्ग कि त्रुटि हैंडलिंग करता है और ठोस काम करने के लिए एक अमूर्त प्रणाली को बुलाती है बनाएँ। (टेम्पलेट विधि पैटर्न)
  • प्रत्येक ऑपरेशन के लिए ठोस वर्ग बनाएँ।

इस आपरेशन आप प्रदर्शन के प्रत्येक प्रकार के नामकरण का लाभ दिया है और आप एक कमान पैटर्न देता है - संचालन वस्तुओं के रूप में प्रतिनिधित्व किया गया है।

07/08/2008 को 12:30
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more