[C#] Rewrite the synchronous method into an asynchronous method
Foreword
When we encounter the need to spend longer In time programs,
We usually call it asynchronously (such as BeginRead, EndRead that reads the data stream),
If it was originally a synchronous method, Is there any way we can rewrite it?
The topic of this article is to introduce how to rewrite a synchronous (sync) program into an asynchronous (async) program.
Practical exercises
In the .Net Framework, asynchronous models (APM) can be roughly divided into two categories,< /p>
The asynchronous model based on IAsyncResult and the asynchronous model of Event Based,
Let’s first create a very simple addition function, and add Thread.Sleep to it to simulate a lot of time ,
public class Calculator
{
public int Calculate(int a, int b)
{
// Simulation spends a lot of time computing
System.Threading.Thread.Sleep(10 * 1000);
return a + b;
}
}
Usually when this function is executed in a program, it will look like this, and the program will be stuck here for a long time
Calculator calculator = new Calculator();
// The program will stop here for a long time
int result = calculator.Calculate(1, 2);
Next, I will introduce how to rewrite this function to be called asynchronously
1. Rewritten to an asynchronous model based on IAsyncResult
First, we must first create a delegate that is the same as the functions Input and Output,
Because the version after 3.5 has built-in Func, so in today’s example, we directly use Func as a delegate,
//In 2.0, sample, not work
//private delegate int CalculateDelegate(int a,int b);
//CalculateDelegate m_calculateDelegate = new CalculateDelegate(Calculate);
private Func
m_calculateDelegate; < br />
After that, we can imitate the BeginRead and EndRead of data stream reading, and write the BeginCalculate and EndCalculate methods respectively,
public IAsyncResult BeginCalculate(int a, int b)
{
this.m_calculateDelegate = this.Calculate;
return this.m_calculateDelegate.BeginInvoke(a, b, null, null);
}
public int EndCalculate(IAsyncResult asyncResult)
{
return this.m_calculateDelegate.EndInvoke(asyncResult);
}
In this way, we can use asynchronous methods to call BeginCalculate and EndCalculate in the program,
And we can continue to do other things before the program is calculated Things,
Calculator calculator = new Calculator();
IAsyncResult asyncResult = calculator.BeginCalculate(1, 2);
// Do something else
int result = calculator.EndCalculate(asyncResult);
?2. Rewritten as the asynchronous model of Event Based?
The asynchronous model of Event Based will be Return the master control to the program.
The current Thread will not be blocked, and the registered event will not be triggered until the execution is completed.
First we create an event that will be triggered when the execution is completed, and will pass in EventArgs with the calculated result
public event EventHandler
CalculateFinished; public class CalculateFinishedEventArgs: EventArgs {public int Result {get; private set;} public CalculateFinishedEventArgs(int result) {this.Result = result ;}}
Let’s create a method called by the program, CalculateAsync, which will not block Thread after execution,
And after the execution is completed, the CalculateFinished event will be triggered,
public void CalculateAsync(int a, int b)
{
this.m_calculateDelegate = Calculate;
AsyncCallback callback = new AsyncCallback(OnCalculateFinished);
this.m_calculateDelegate.BeginInvoke(a, b, callback, m_calculateDelegate);
}
private void OnCalculateFinished(IAsyncResult asyncResult)
{
Func calculateDelegate = (Func)asyncResult.AsyncState;
int result = calculateDelegate.EndInvoke(asyncResult);
EventHandler temp = CalculateFinished;
if (temp != null)
{
temp(this, new CalculateFinishedEventArgs(result));
}
}
,>,>
Executing the program can be rewritten as follows
Calculator calculator = new Calculator();
calculator.CalculateFinished += (o, args) => MessageBox.Show(string.Format("Result is {0}", args.Result));
calculator.CalculateAsync(1, 2);
// Do other works...
Concluding remarks
In order to effectively utilize system resources, work in parallel , And provide users with a good user experience,
It is indispensable to use asynchronous method calls when writing programs,
But when writing asynchronous programs, it is often It will cause the program to be more fragmented,
and not easy to read and maintain. In the next article,
will introduce how to use Iterator to improve this situation,< /p>
Of course, you can also use the asynchronous call method introduced earlier and jump out of the processing window.
Use BackgroundWorker or Thread to process it.
Everyone is also welcome Let’s discuss and advise more ^_^
Reference data:
1. http://msdn.microsoft.com/zh-tw/library /2e08f6yc(v=VS.100).aspx calls synchronous methods asynchronously
2. http://msdn.microsoft.com/zh-tw/magazine/cc163467.aspx Practice CLR asynchronous programs Compose model
Original text: Large column [C#] Rewrite synchronous method into asynchronous method