Several ways to realize asynchronous to synchronous

Loop waiting to realize asynchronous to synchronous

In the loop await, we can use a variable to indicate whether the asynchronous operation has completed or not. We can then check that variable in the loop and exit the loop if it indicates that the asynchronous operation is complete.

Otherwise, we can make the thread wait for a while and check the variable again. This way, we can wait for the asynchronous operation to complete without keeping the thread stuck for a long time.

For example, suppose we want to perform an asynchronous operation that returns a result asynchronously. We can use the following code to implement circular waiting:

// 创建一个标志变量,表示异步操作是否已完成
var isDone = false;

// 开始执行异步操作
doAsyncOperation(() -> {
    
    
  // 当异步操作完成时,将标志变量设为 true
  isDone = true;
});

// 在循环中检查标志变量,直到异步操作完成
while (!isDone) {
    
    
  // 等待一段时间
  Thread.sleep(100);
}

// 异步操作已完成,可以执行后续操作

We used a simple loop wait in the above example to achieve asynchronous to synchronous, but this method is not optimal. First, it blocks the thread, which means the thread is stuck until the asynchronous operation completes. This can cause performance issues.

Another problem is that if an asynchronous operation doesn't return a result, we can't be sure it's completed. In this case, we may need to provide a timeout after which the loop exits. But there is a problem with this, that is, if the timeout period is too short, the program may not work properly; if the timeout period is too long, the waiting time will be increased.

Therefore, in order to solve these problems, we should use a more advanced method to achieve asynchronous conversion, such as using one of the following methods:

  1. Use a callback function: After the asynchronous operation is completed, the callback function is called to notify the program.
  2. Use events: When an asynchronous operation is completed, an event is triggered, and the program can listen to this event and respond.
  3. Use Future or Promise: These objects can represent a future value, and when the asynchronous operation completes, they return the result.

The advantage of the above methods is that they do not block the thread, allowing the thread to continue performing other tasks. In addition, these methods can provide more flexibility, such as allowing the program to respond immediately after the completion of the asynchronous operation, or to perform other operations while waiting for the operation to complete.

Callback function to realize asynchronous to synchronous

Suppose we want to perform an asynchronous operation that returns an integer value asynchronously. We can use the callback function to achieve asynchronous to synchronous, as follows:

// 定义一个变量,用来保存异步操作的结果
var result = 0;

// 执行异步操作,并提供一个回调函数
doAsyncOperation((int value) => {
    
    
  // 在回调函数中,将异步操作的结果保存到 result 中
  result = value;
  
  // 执行后续操作
  Console.WriteLine($"Result: {result}");
});

// 在这里,我们可以继续执行其他任务,直到异步操作完成

// 当我们需要使用异步操作的结果时,可以直接使用 result 变量

As you can see, we need to perform subsequent operations in the callback function instead of directly in the main thread. This is because when the asynchronous operation is completed, we need to notify the main thread through the callback function before performing subsequent operations.

Use events to achieve asynchronous to synchronous

We can also use events to achieve asynchronous to synchronous, as follows:

// 定义一个事件,用来通知程序异步操作已完成
event EventHandler asyncOperationCompleted;

// 定义一个变量,用来保存异步操作的结果
var result = 0;

// 执行异步操作,并在完成后触发 asyncOperationCompleted 事件
doAsyncOperation(() => {
    
    
  asyncOperationCompleted?.Invoke(this, EventArgs.Empty);
});

// 在这里,我们可以继续执行其他任务,直到异步操作完成

// 监听 asyncOperationCompleted 事件,并在事件处理程序中执行后续操作
asyncOperationCompleted += (sender, args) => {
    
    
  // 在事件处理程序中,我们可以使用 result 变量来访问异步操作的结果
  Console.WriteLine($"Result: {result}");
};

It can be seen that when using events to achieve asynchronous conversion, subsequent operations must also be performed in the event handler instead of the main thread. This is because when an asynchronous operation completes, we need to notify the main thread through an event before we can perform subsequent operations.

Implemented using Future or Promise

Using Future or Promise can also achieve asynchronous to synchronous conversion, as shown below:

// 创建一个 Future 对象,用来保存异步操作的结果
var future = new Future<int>();

// 执行异步操作,并在完成后调用 Future 的 SetResult 方法
doAsyncOperation((int value) => {
    
    
  future.SetResult(value);
});

// 在这里,我们可以继续执行其他任务,直到异步操作完成

// 使用 Future 的 GetResult 方法获取异步操作的结果,并执行后续操作
var result = future.GetResult();
Console.WriteLine($"Result: {result}");

It can be seen that when using Future or Promise to achieve asynchronous conversion, subsequent operations must be performed after calling the GetResult method, rather than in the main thread. This is because when the asynchronous operation is completed, we need to notify the main thread through the SetResult method of Future or Promise, and then we can perform subsequent operations.

Summarize

By using advanced methods such as callback functions, events, or Future/Promise, we can achieve asynchronous conversion more elegantly, avoiding the disadvantages of circular waiting.

It should be noted that when methods such as callback functions, events, or Future/Promise are used, the execution flow of the program will change. Because the asynchronous operation is performed in another thread, when the asynchronous operation is completed, we need to notify the main thread through callback function, event or Future/Promise, etc., and then we can perform subsequent operations.

Guess you like

Origin blog.csdn.net/Ber_Bai/article/details/128196452