Deploying RegEx Timeout in .NET 4

Platform: Silverlight 4, .NET 4

When previewing .NET 4.5, the RegEx class was extended to allow a timeout value to be set that would prevent the RegEx engine from depending on the user interface if there were problems with pattern matching.

Request for proposals for the implementation of similar functionality in the .NET 4 Silverlight application.

Thanks in advance.

+6
source share
4 answers

General example:

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(); } 

Application:

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

Update:

As pointed out by Christian.K, the asynchronous thread will continue to work.

This is where the stream ends:

 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; } 

Update:

Fixed above snippet to handle exceptions correctly.

+10
source

It is not so simple, but it can be done using two threads, with the first execution of the regular expression, the second - the first, if itruns is too long. However, this in itself is problematic.

+3
source

I re-executed the above code, changing it in such a way that I believe is more reliable.

  /// <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! } 
+2
source

The standard way to get a timeout for something that does not come with this function is to simply run everything you want to process in a separate thread, and then in your main thread you use Thread.Join with the appropriate timeout.

+1
source

Source: https://habr.com/ru/post/909426/


All Articles