.NET Frameworkから.NET Core移行時における非同期処理のポイント
こんにちは。クレスコ・デジタルテクノロジーズのふーこです。
2023年度に未経験で入社し、ソフトウェアの運用の案件に2年程携わっています。
今回は、C#での非同期処理の実装についての簡単な説明と、
.Netにおける非同期処理の実装において、.Net Frameworkから.Net Core移行時の注意点をご説明します。
■あわせて読まれている資料:
非同期処理の概要と実装例
C#の非同期処理は、アプリケーションの応答性を向上させるための方法の一つであり、主にasyncおよびawaitキーワードを使用して、非同期メソッドを簡潔に記述することができます。本章では、同期処理の基本概念とその実装方法について説明します。
非同期処理とは?
非同期処理とは、長時間かかる処理を別スレッドで実行し、その処理が完了するまでメインの処理をブロックしない方法です。
これにより、アプリケーションの応答性が向上し、ユーザエクスペリエンスが改善されます。
非同期処理は以下のキーワードを用いて実装します。
■asyncおよびawaitキーワード
-
asyncキーワード
メソッドの定義に付けることで、そのメソッドが非同期に実行できることを示します。
asyncメソッドは必ずTaskまたはTask<T>を返す必要があります。戻り値の型がvoidの場合、そのメソッドはイベントハンドラ専用として使われることが一般的です。
-
awaitキーワード
非同期メソッド内で、非同期処理が完了するのを待つために使用します。awaitは、TaskまたはTask<T>型の結果を待機し、処理が完了するまでメソッドの実行を一時停止します。
非同期処理の完了後、結果が返されると、メソッドの実行が再開します。
非同期処理の実装例
前述したasyncおよびawaitキーワードを用いて、非同期メソッドを実装する場合の例です。
using System; |
この例では、”PerformLongRunningTaskAsync”メソッドが3秒間非同期に待機する間、メイン処理はブロックされずに「開始」と「完了」を表示します。Task.Delayは指定された時間だけ非同期に待機しますが、メイン処理は他の処理を続けることができます。
このように、C#の非同期処理は、asyncおよびawaitキーワードを用いて簡単に実装することができ、アプリケーションのパフォーマンスや応答性を向上させるために非常に有用です。非同期メソッドを正しく使うことで、長時間かかる処理でもアプリケーションの他の部分に影響を与えることなく、スムーズに実行できます。
.Net Frameworkの非同期処理を.Net Coreへ移行する際の注意点
ここからは、非同期処理を.NETで実装している場合に起こりうる問題点について説明します。
.NET Frameworkで BeginInvokeおよびEndInvokeメソッドを実装しているプログラムを.NET Coreへ移行する場合は、コードの修正が必要になります。これらのメソッドがなぜ.NET Coreでサポートされていないのか、また、それらのメソッドを使わずにコードを修正する方法について解説します。
BeginInvokeとEndInvokeメソッドの概要
■BeginInvokeとEndInvokeメソッドの概要
BeginInvokeメソッドは、デリゲートの非同期呼び出しを実行するためのものです。
非同期呼び出しを開始し、IAsyncResultオブジェクトを返します。このオブジェクトを使って、呼び出しの完了を待ち、結果を取得するためにEndInvokeメソッドを使用します。
以下に簡単なコーディング例を示します。
delegate int WorkDelegate(int arg); // 非同期処理の呼び出し |
■.NET Coreでのサポート状況
Asynchronous Programming Model (APM)であるBeginInvokeおよびEndInvokeメソッドは、.NET Frameworkでは使用できますが、.NET Coreではサポートされていません。これは、非同期デリゲートの実装が.NET Coreでサポートされていないリモーティング機能に依存しているためです。
そのため、.NET Coreではこれらのメソッドを使用するとエラー
”System.PlatformNotSupportedException”が発生します。
タスクベースの非同期パターンへの修正方法
.NET Coreで非同期処理を実装する場合は、BeginInvokeとEndInvokeの代わりに、タスクベースの非同期パターン(TAP)を使用することが推奨されます。選択肢として以下の2つのアプローチがあります。
■タスクベースの非同期メソッドの使用
呼び出すAPIに対してタスクベースの非同期メソッドが提供されている場合、それを使用するのが最も簡単で効果的な修正方法です。例えば、APIがTaskを返す非同期メソッドを提供している場合、そのメソッドを呼び出すようにコードを修正します。
■Task.Runの使用
タスクベースの非同期メソッドが提供されていない場合、Task.Runを使ってスレッドプールで処理を実行することができます。BeginInvokeの代わりにTask.Runを使い、EndInvokeの代わりにawaitでタスクの完了を待ちます。
以下は、前項で記述した”BeginInvoke”および”EndInvoke”を使用したコードを”Task.Run”を使ったコードに置き換えた例です。
delegate int WorkDelegate(int arg); //非同期処理の呼び出し |
上記のように実装することで、Task.Runを使ってデリゲートのInvokeメソッドを実行し、処理が完了するまで待つことができます。これにより、.NET Coreでの非同期処理を適切に行うことが可能となります。
以上のように、.NET Frameworkから.NET Coreに移行する際は、非同期処理のモデルを最新の非同期パターンであるタスクベースの非同期パターン(TAP)に更新することが推奨されています。
まとめ
今回はC#の非同期処理と.Netのバージョンアップ対応時の注意点についてご紹介しました。
非同期処理の実装方法について、ここでは書ききれていないことも多いですが、
この記事がどなたかのお役に立てれば幸いです。
最後までお読みいただきありがとうございました。
■サービス資料一覧はこちら↓
引用元
Migrating Delegate.BeginInvoke Calls for .NET Core:
https://devblogs.microsoft.com/dotnet/migrating-delegate-begininvoke-calls-for-net-core/