2012-02-27 16 views
6

प्लेटफार्म: सिल्वरलाइट 4, .NET 4कार्यान्वयन रेगुलर एक्सप्रेशन से समय समाप्त 4

.NET 4.5 डेवलपर पूर्वावलोकन RegEx वर्ग जो फांसी से रेगुलर एक्सप्रेशन से इंजन रोका जा सके एक समय समाप्ति मूल्य की स्थापना की अनुमति के लिए बढ़ाया गया है के साथ

यदि यूआई पैटर्न पैटर्न के साथ समस्या है तो यूआई।

.NET 4 सिल्वरलाइट एप्लिकेशन में समान कार्यक्षमता को लागू करने के लिए सुझावों का अनुरोध करना।

अग्रिम धन्यवाद।

+0

कार्य का उपयोग करके यह जवाब भी देखें: http://stackoverflow.com/a/13526507/492 ... मुझे नहीं पता कि यह सिल्वरलाइट में काम करता है या नहीं। –

उत्तर

10

जेनेरिक उदाहरण:

public static R WithTimeout<R>(Func<R> proc, int duration) 
{ 
    var wh = proc.BeginInvoke(null, null); 

    if (wh.AsyncWaitHandle.WaitOne(duration)) 
    { 
    return proc.EndInvoke(wh); 
    } 

    throw new TimeOutException(); 
} 

उपयोग:

var r = WithTimeout(() => regex.Match(foo), 1000); 

अद्यतन:

रूप Christian.K से कहा, async धागा अभी भी चलते रहेंगे ।

यहाँ एक जहां धागा समाप्त कर देगा है:

public static R WithTimeout<R>(Func<R> proc, int duration) 
{ 
    var reset = new AutoResetEvent(false); 
    var r = default(R); 
    Exception ex = null; 

    var t = new Thread(() => 
    { 
    try 
    { 
     r = proc(); 
    } 
    catch (Exception e) 
    { 
     ex = e; 
    } 
    reset.Set(); 
    }); 

    t.Start(); 

    // not sure if this is really needed in general 
    while (t.ThreadState != ThreadState.Running) 
    { 
    Thread.Sleep(0); 
    } 

    if (!reset.WaitOne(duration)) 
    { 
    t.Abort(); 
    throw new TimeoutException(); 
    } 

    if (ex != null) 
    { 
    throw ex; 
    } 

    return r; 
} 

अद्यतन:

स्निपेट के ऊपर फिक्स्ड सही ढंग से अपवादों के साथ निपटने के लिए।

+2

लेकिन क्या टाइमआउट होने पर यह भी (पृष्ठभूमि) पृष्ठभूमि में चलना जारी नहीं रखेगा? –

+0

@ ईसाई.के: मैंने ऐसा सोचा, लेकिन ऐसा लगता है कि आप सही हैं!धन्यवाद :) इस के लिए ड्राइंग बोर्ड पर वापस! – leppie

+0

@ ईसाई.के: अद्यतन उत्तर :) – leppie

3

यह इतना आसान नहीं है - लेकिन यह दो धागे का उपयोग कर रेगेक्स करने वाले पहले के साथ किया जा सकता है, दूसरी बार अगर यह बहुत लंबा होता है तो पहला थ्रेड मारता है। हालांकि, यह खुद में समस्याग्रस्त है।

+1

+1 स्वीकार करने के लिए +1 "हालांकि यह स्वयं में समस्याग्रस्त है"। :-) –

+0

अफसोस की बात यह है कि यह केवल वही है जो रेगेक्स विधि का समर्थन करता है; (हालांकि, यह बहुत अच्छी बात है, लेकिन ... अच्छी तरह से ... .NET 4.5 यहां मैं आ रहा हूं ... इस सप्ताह – TomTom

1

किसी चीज़ पर टाइमआउट प्राप्त करने का मानक तरीका जो पहले से ही सुविधा के साथ नहीं आता है, बस एक अलग थ्रेड पर प्रक्रिया करना चाहते हैं, और फिर अपने मुख्य धागे में, आप थ्रेड का उपयोग करें। उपयुक्त टाइमआउट।

+1

लेकिन ध्यान रखें कि अन्य थ्रेड चलना बंद नहीं होता है, सिर्फ इसलिए कि आपका जॉइन-टाइमआउट समाप्त हो गया है। अगर कोई इसके साथ रह सकता है, तो ठीक है। हालांकि, फ्रीक्वेंसी रेगेक्स धागे के आधार पर मेरा प्रारंभ होना चाहिए (अधीर उपयोगकर्ता एक लिंक/बटन), जो चलने वाले धागे और प्रयुक्त संसाधनों का पूरा समूह हो सकता है। पृष्ठभूमि में रन-दूर रेगेक्स "जलने" सीपीयू के बारे में बात न करें। –

+0

जाहिर है, अगर आप इसे जारी रखना नहीं चाहते हैं, तो आप एक जोड़ते हैं थ्रेड। समय समाप्ति के बाद ... लेकिन कुछ मामलों में आप केवल जीयूआई पर एक चेतावनी पॉप अप करना चाहते हैं कि "यह अपेक्षा से अधिक समय ले रहा है" – Cine

+0

हां, लेकिन वह "स्पष्ट" हिस्सा नया रेगेक्स-टाइमआउट है .NET 4.5 में समर्थन करता है - और कठिन एक ('Thread.Abort' यह है मुद्दों का अपना सेट)। –

2

मैंने उपरोक्त कोड को इस तरह से बदल दिया है कि मैं विश्वास करता हूं कि मैं विश्वास अधिक विश्वसनीय हूं।

/// <summary> 
    /// Executes function proc on a separate thread respecting the given timeout value. 
    /// </summary> 
    /// <typeparam name="R"></typeparam> 
    /// <param name="proc">The function to execute.</param> 
    /// <param name="timeout">The timeout duration.</param> 
    /// <returns></returns> 
    public static R ExecuteWithTimeout<R>(Func<R> proc, TimeSpan timeout) { 
     var r = default(R); // init default return value 
     Exception ex = null; // records inter-thread exception 

     // define a thread to wrap 'proc' 
     var t = new Thread(() => { 
      try { 
       r = proc(); 
       } 
      catch (Exception e) { 
       // this can get set to ThreadAbortException 
       ex = e; 

       Debug.WriteLine("Exception hit"); 

       } 
      }); 

     t.Start(); // start running 'proc' thread wrapper 
     // from docs: "The Start method does not return until the new thread has started running." 

     if (t.Join(timeout) == false) { 
      t.Abort(); // die evil thread! 
      // Abort raises the ThreadAbortException 
      int i = 0; 
      while ((t.Join(1) == false) && (i < 20)) { // 20 ms wait possible here 
       i++; 
       } 
      if (i >= 20) { 
       // we didn't abort, might want to log this or take some other action 
       // this can happen if you are doing something indefinitely hinky in a 
       // finally block (cause the finally be will executed before the Abort 
       // completes. 
       Debug.WriteLine("Abort didn't work as expected"); 
       } 
      } 

     if (ex != null) { 
      throw ex; // oops 
      } 
     return r; // ah! 
     } 
संबंधित मुद्दे