GrapeCity Secure FTP for .NET 4.0J > 基本的な使用方法 > コンポーネントの使用手順 > 非同期処理を実装する |
ここでは、非同期処理を実装する手順について説明します。
非同期処理を行う場合、旧バージョン(FTP for .NET 1.0J/Secure FTP 2.0J)では複雑なコード処理が必要でした。たとえば、サーバーから非同期でリストを取得する場合、同期処理の場合とは異なる専用のメソッド(Ftp.BeginListメソッド)を実行し、さらにリスト取得処理の終了時に発生する専用のイベント(Ftp.EndListイベント)に処理を実装する必要があり、その結果メンテナンスしにくいイベント駆動型のコードになっていました。
本バージョンでは、それらのメソッドやイベントに代わり、新たにStartメソッドやMarshalメソッドが用意され、シンプルな実装で非同期処理が可能となりました。各メソッドの使用方法について、以下に説明します。
本製品のメソッドは、同期処理と非同期処理(ブロッキング用途と非ブロッキング用途)の両方をサポートしています。ただし、メソッドを単純に実行した場合、それは同期処理で実行されます。
本バージョンで導入されたStartメソッドは、渡された関数を別のワーカースレッドで実行する機能です。つまり、本製品のメソッドが含まれる関数をStartメソッドに渡すだけで、その関数は呼び出し元のメインスレッドのUIをブロックすることなく、非同期処理で実行されます。このメソッドの構文は単純です。
続きを読む
Visual Basic |
コードのコピー |
---|---|
Ftp1.Start(AddressOf myBlockingFunction, myObject) ' ブロッキング処理のメソッドが含まれる関数です。 Private Sub myBlockingFunction(ByVal myObject As Object) .... End Sub |
C# |
コードのコピー |
---|---|
ftp1.Start(myBlockingFunction, myObject); // ブロッキング処理のメソッドが含まれる関数です。 private void myBlockingFunction(object myObject) { .... } |
このアプローチには、以下のような利点があります。
同期処理と非同期処理とで、一つの関数を共用できます。関数を別個に作成する必要はありません。Startメソッドを使用すれば非同期で、Startメソッドを使用しなければ同期処理で、呼び出した関数が実行されます。
関数内のメソッドは直列に呼び出されるので、コードのメンテナンスが容易です。多数のイベントハンドラを実装し、あるハンドラから別のハンドラにジャンプするようなコードを記述する必要はありません。
Startメソッドを使用して呼び出された関数は、別のワーカースレッドで実行されます。そこから呼び出し元のメインスレッド(UIスレッド)へ結果やデータを戻す(マーシャリングする)場合には、その関数内でMarshalメソッドを実行します。
Marshalメソッドを実行すると、メソッドの引数の種類により、メインスレッドでListingイベントなどのイベントが発生します。それらのイベントハンドラ内で、Marshalメソッドの引数として渡されたデータを受け取ることができます。
続きを読む
以下のコードは、Startメソッドで呼び出す関数内でListメソッドを実行し、その結果を呼び出し元のメインスレッド(UIスレッド)へマーシャリングする例です。
このコードにおけるMarshalメソッドの実行時には、メインスレッド側でListingイベントが発生します。このListingイベントのイベントハンドラ内で、渡されたデータをListBoxへセットしています。
Visual Basic |
コードのコピー |
---|---|
Private Sub getListing(ByVal state As Object) Dim listing As Listing = Ftp1.List("", "", ListType.Full) ' Listメソッドの結果をマーシャリングします。 Ftp1.Marshal(listing, "", Nothing) End Sub Private Sub Ftp1_Listing(ByVal sender As Object, ByVal e As ListingEventArgs) Handles Ftp1.Listing ' リストに含まれるすべてのリスト項目をリストボックスに追加します。 For Each entry in e.Listing ListBox1.Items.Add(entry.Text) Next entry End Sub |
C# |
コードのコピー |
---|---|
private void getListing(object state) { Listing listing = ftp1.List("", "", ListType.Full); // Listメソッドの結果をマーシャリングします。 ftp1.Marshal(listing, "", null); } private void ftp1_Listing(object sender, ListingEventArgs e) { // リストに含まれるすべてのリスト項目をリストボックスに追加します。 foreach (ListEntry entry in e.Listing) listBox1.Items.Add(entry.Text); } |
Startメソッドを使用せずに、同期処理として呼び出した関数内でMarshalメソッドが実行されても、動作上特に問題はありません。 |
StartメソッドとMarshalメソッドを使用して、非同期処理を実現する手順例を、以下に示します。
続きを読む
「フォームに貼り付けて使用する」の手順1.〜3.の方法で、フォームにFtpコンポーネントを貼り付けます。
フォームに標準のButtonコントロール、TextBoxコントロール、ListBoxコントロールを貼り付けます。
「イベント処理を実装する」の「フォームに張り付けて使用する場合」の手順1.〜3.の方法で、Ftp1([Visual C#]の場合は「ftp1」)コンポーネントに、ListingイベントとErrorイベントのイベントハンドラを追加します。
フォーム上のButtonコントロールをダブルクリックして、Clickイベントのイベントハンドラを追加します。
追加したイベントハンドラに、以下のコードを記述します。
Visual Basic |
コードのコピー |
---|---|
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles button1.Click ' 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 Dim session As New FtpSession() session.RemoteEndPoint.HostNameOrAddress = "myFtpServer" session.Username = "myUsername" session.Password = "myPassword" ' 非同期でリストを取得します。 Ftp1.Start(AddressOf getListing, session) End Sub Private Sub getListing(ByVal state As Object) Try ' FTPサーバーにログインしてリストを取得します。 Ftp1.Session = TryCast(state, FtpSession) Ftp1.Connect() Ftp1.Authenticate() Dim listing As Listing = Ftp1.List("", "", ListType.Full) ' リストをUIスレッドにマーシャリングします。 Ftp1.Marshal(listing, "", Nothing) Catch ex As Exception Ftp1.Marshal(ex) Finally ' FTPサーバーとの接続を閉じます。 Ftp1.Close() End Try End Sub Private Sub Ftp1_Listing(ByVal sender As Object, ByVal e As ListingEventArgs) Handles Ftp1.Listing ' リストに含まれるすべてのリスト項目をリストボックスに追加します。 For Each entry As ListEntry In e.Listing ListBox1.Items.Add(entry.Text) Next entry End Sub Private Sub Ftp1_Error(ByVal sender As Object, ByVal e As ErrorEventArgs) Handles Ftp1.Error ' エラーメッセージをテキストボックスに追加します。 TextBox1.AppendText(e.GetException().Message) End Sub |
C# |
コードのコピー |
---|---|
private void button1_Click(object sender, EventArgs e) { // 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 FtpSession session = new FtpSession(); session.RemoteEndPoint.HostNameOrAddress = "myFtpServer"; session.Username = "myUsername"; session.Password = "myPassword"; // 非同期でリストを取得します。 ftp1.Start(getListing, session); } private void getListing(object state) { try { // FTPサーバーにログインしてリストを取得します。 ftp1.Session = state as FtpSession; ftp1.Connect(); ftp1.Authenticate(); Listing listing = ftp1.List("", "", ListType.Full); // リストをUIスレッドにマーシャリングします。 ftp1.Marshal(listing, "", null); } catch (Exception ex) { // エラーをUIスレッドに報告します。 ftp1.Marshal(ex); } finally { // FTPサーバーとの接続を閉じます。 ftp1.Close(); } } private void ftp1_Listing(object sender, ListingEventArgs e) { // リストに含まれるすべてのリスト項目をリストボックスに追加します。 foreach (ListEntry entry in e.Listing) listBox1.Items.Add(entry.Text); } void ftp1_Error(object sender, ErrorEventArgs e) { // エラーメッセージをテキストボックスに追加します。 textBox1.AppendText(e.GetException().Message); } |
[デバッグ]メニューの[デバッグ開始]を選択すると、アプリケーションがビルドされ、実行されます。
フォーム上のボタンをクリックすると、FTPサーバーから取得したリストがListBox上に表示されます。getListing関数は非同期で実行されているので、リストが表示されるまでの間もフォームの操作が可能になっています。
上記サンプルコードのgetListing関数は、Startメソッドを使用せずに呼び出すこともできます。この場合は同期処理で実行されます。 |