Implementation of function running timeout in C #

Source: Internet
Author: User

The BeginInvoke method and the ManualResetEvent class are mainly used for implementation.
BeginInvoke enables the function to run asynchronously in the thread pool. After running, the callback function is called.
ManualResetEvent is used for Synchronous blocking.
The design philosophy is as follows:
When a function runs asynchronously on a thread in the thread pool, ManualResetEvent blocks the current thread and waits for some time.
During the waiting period, if the asynchronous function is completed, a signal will be set for ManualResetEvent so that the blocked thread can continue to run.
If the wait times out, the blocked thread will also cancel the blocking and continue to run, but will ignore the callback function. (Even if the callback function is still called), in fact, all the threads created by BeginInvoke are backend threads. For example, once all the front-end threads exit (the main thread is a front-end thread ), the background thread ends and exits regardless of whether the execution is complete. Therefore, if the blocked main thread is completely running and exited, the asynchronous running thread also exits, whether or not it is running.
The isGetSignal = manu. WaitOne (timeout) statement is to block the current thread for a period of time.
During the blocking period, isGetSignal is not assigned a value until the blocking is canceled. A value is returned to isGetSignal.
If the blocking is canceled because the signal is received, the value is true.
If the blocking is canceled because of timeout, the value is false.
The process is as follows:

Encapsulate the code logic into a class.
This class accepts a delegate and a timeout value as the constructor.
Write the delegate and ManualResetEvent. Set (); statement in a method body and CombineActionAndManuset. Therefore, the call to CombineActionAndManuset is to Set the cancel blocking signal after the method is run.
Encapsulated code:
Public class FuncTimeout
{
/// <Summary>
/// Semaphores
/// </Summary>
Public ManualResetEvent manu = new ManualResetEvent (false );
/// <Summary>
/// Whether the signal is received
/// </Summary>
 
Public bool isGetSignal;
/// <Summary>
/// Set the timeout value
/// </Summary>
Public int timeout;
/// <Summary>
/// A delegate of the method to be called
/// </Summary>
Public Action <int> FunctionNeedRun;
 
/// <Summary>
/// Constructor, input timeout time and Running Method
/// </Summary>
/// <Param name = "_ action"> </param>
/// <Param name = "_ timeout"> </param>
Public FuncTimeout (Action <int> _ action, int _ timeout)
{
FunctionNeedRun = _ action;
Timeout = _ timeout;
}
 
/// <Summary>
/// Callback function
/// </Summary>
/// <Param name = "ar"> </param>
Public void MyAsyncCallback (IAsyncResult ar)
{
// The value of isGetSignal is false, indicating that the asynchronous method has exceeded the set time, And the callback method is no longer required.
If (isGetSignal = false)
{
Console. WriteLine ("discard callback function execution ");
Thread. CurrentThread. Abort ();
}
Else
{
Console. WriteLine ("Call callback function ");
}
}
 
/// <Summary>
/// Call a function
/// </Summary>
/// <Param name = "param1"> </param>
Public void doAction (int param1)
{
Action <int> WhatTodo = CombineActionAndManuset;
// Use the BeginInvoke method to asynchronously execute the method on the thread pool.
Var r = WhatTodo. BeginInvoke (param1, MyAsyncCallback, null );
// Set blocking. If the above BeginInvoke method runs before timeout, manu will receive a signal. In this case, isGetSignal is true.
// If no signal is received within the timeout period, that is, if the asynchronous method is not completed, isGetSignal is false.
IsGetSignal = manu. WaitOne (timeout );

If (isGetSignal = true)
{
Console. WriteLine ("after the function is run, the setting signal is received, and asynchronous execution does not Time Out ");
}
Else
{
Console. WriteLine ("no signal is received, asynchronous execution times out ");
}
}
 
/// <Summary>
/// Merge the methods to be passed in with the manu. Set () method into a method body.
/// After the action method is run, set the semaphore to cancel blocking.
/// </Summary>
/// <Param name = "num"> </param>
Public void CombineActionAndManuset (int num)
{
FunctionNeedRun (num );
Manu. Set ();
}
}
Test code:
 
Class Program
{
Static void Main (string [] args)
{
FuncTimeout ft = new FuncTimeout (dothings, 3000 );
Ft. doAction (6 );
}
 
Static void dosomething (int num)
{
For (int I = 0; I <num; I ++)
{
Thread. Sleep (500 );
Console. Write (I );
}
}
}
 
The method does not time out when the timeout value is set to 5s.

The method times out when the timeout value is set to 1 s.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.