非同期から同期を実現するいくつかの方法

非同期から同期への実現を待つループ

ループ await では、変数を使用して、非同期操作が完了したかどうかを示すことができます。次に、ループ内でその変数をチェックし、非同期操作が完了したことを示している場合はループを終了できます。

それ以外の場合は、スレッドをしばらく待機させて、変数を再度チェックすることができます。このようにして、スレッドを長時間スタックさせたままにすることなく、非同期操作が完了するのを待つことができます。

たとえば、非同期で結果を返す非同期操作を実行したいとします。次のコードを使用して、循環待機を実装できます。

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

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

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

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

上記の例では、単純なループ待機を使用して非同期から同期を実現しましたが、この方法は最適ではありません。まず、スレッドをブロックします。これは、非同期操作が完了するまでスレッドが停止することを意味します。これにより、パフォーマンスの問題が発生する可能性があります。

もう 1 つの問題は、非同期操作が結果を返さない場合、それが完了したことを確認できないことです。この場合、ループが終了した後にタイムアウトを提供する必要があるかもしれません。しかし、これには問題があり、タイムアウト期間が短すぎるとプログラムが正しく動作しない可能性があり、タイムアウト期間が長すぎると待ち時間が長くなります。

したがって、これらの問題を解決するには、次のいずれかの方法を使用するなど、より高度な方法を使用して非同期変換を実現する必要があります。

  1. コールバック関数を使用する: 非同期操作が完了すると、コールバック関数が呼び出されてプログラムに通知されます。
  2. イベントを使用する: 非同期操作が完了すると、イベントがトリガーされ、プログラムはこのイベントをリッスンして応答できます。
  3. Future または Promise を使用する: これらのオブジェクトは将来の値を表すことができ、非同期操作が完了すると結果を返します。

上記の方法の利点は、スレッドをブロックしないため、スレッドが他のタスクを実行し続けることができることです。さらに、これらのメソッドは、プログラムが非同期操作の完了直後に応答したり、操作の完了を待っている間に他の操作を実行したりできるようにするなど、柔軟性を高めることができます。

非同期から同期を実現するコールバック関数

整数値を非同期的に返す非同期操作を実行したいとします。次のように、コールバック関数を使用して非同期から同期を実現できます。

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

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

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

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

ご覧のとおり、メイン スレッドで直接ではなく、コールバック関数で後続の操作を実行する必要があります。これは、非同期操作が完了すると、後続の操作を実行する前に、コールバック関数を介してメイン スレッドに通知する必要があるためです。

イベントを使用して非同期から同期を実現する

次のように、イベントを使用して非同期から同期を実現することもできます。

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

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

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

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

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

イベントを使用して非同期変換を実現する場合、後続の操作もメイン スレッドではなくイベント ハンドラーで実行する必要があることがわかります。これは、非同期操作が完了すると、後続の操作を実行する前に、イベントを通じてメイン スレッドに通知する必要があるためです。

Future または Promise を使用して実装

以下に示すように、Future または Promise を使用すると、非同期から同期への変換も実現できます。

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

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

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

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

Future または Promise を使用して非同期変換を実現する場合、メイン スレッドではなく、GetResult メソッドを呼び出した後に後続の操作を実行する必要があることがわかります。これは、非同期操作が完了したときに、Future または Promise の SetResult メソッドを介してメイン スレッドに通知する必要があり、その後の操作を実行できるためです。

要約する

コールバック関数、イベント、Future/Promise などの高度なメソッドを使用することで、非同期変換をよりエレガントに実現し、循環待機の欠点を回避できます。

コールバック関数、イベント、Future/Promise などのメソッドを使用すると、プログラムの実行フローが変わることに注意してください。非同期操作は別のスレッドで実行されるため、非同期操作が完了したら、コールバック関数、イベント、または Future/Promise などを介してメイン スレッドに通知する必要があり、その後の操作を実行できます。

おすすめ

転載: blog.csdn.net/Ber_Bai/article/details/128196452