0

これまでのところ、Windowsフォーム内でFTPオブジェクトを使用しています。FTPオブジェクトは別のスレッドで実行されるため、アプリがフリーズしないようにするために、次のコードを使用します。

private void OnResponse(string response)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new StringDelegate(OnResponse), new object[] { response });
            return;
        }
    } //end of OnResponse

文字列デリゲートが何であるかは完全にはわかりませんが、これは機能します。

しかし、私は現在リファクタリングを行っており、ftpをクラスに隠したいと思っています。私の質問は、メインスレッドがフリーズしないようにするにはどうすればよいですか?クラス内でイベントを発生させることに関するオンラインのすべての参照は理にかなっていますが、アプリケーションがマルチスレッド化されている例は1つも見つかりませんでした。私の最大の懸念はInvokeRequiredです。

上記のコードでは、これはフォームです。次のようなクラス内でftpオブジェクトを非表示にした場合:

abstract class MyClass
{
    //data members
    private FTP _ftp;

    //other data members, methods, and properties etc
}

「これ」はMyClassの対象になります。InvokeRequiredプロパティがクラスに実装されているかどうかはわかりません(おそらく、そのプロパティを持つ特別なインターフェイスを実装する必要がありますか?)。または、何かが足りず、クラス内でマルチスレッドオブジェクトを使用することは想定されていませんか?

4

2 に答える 2

1

UIスレッドで作成されたコントロールまたはコントロールから派生したもの(フォームである必要はありません)が必要です。MyClassはUIを直接更新するべきではない可能性が高いため、ここではあまり関係ありません。MyClassはおそらくイベントを発生させるか、コールバックを呼び出します。

FTPライブラリからのイベントに基づいてフォーム上の何かを変更したい場合、重要になるのはUIです。そのためには、UIスレッドで作成されたコントロールまたはコントロールから派生したもの(ここでもフォームである必要はありません)が必要です。そのコントロールを使用してInvokeRequiredをチェックし、それがtrueの場合は、Invokeを呼び出します。オリジナルはカスタムデリゲートを使用していますが(私にはよく知られているので、おそらくFTPサンプルからのものです)、任意のデリゲートを使用できます。

Control.Invokeを使用するための例はウェブ上にたくさんあるので、かなり簡単に実装できるはずです。

于 2009-05-22T21:12:23.127 に答える
0

これを設計する最も可能性の高い方法は、必要に応じて「MyClass」の呼び出し元を呼び出すか、呼び出さないようにすることです。応答が発生したときにイベントを発生させるようにクラスを設計します。

メインスレッドに呼び出す必要があるのは、WindowsUIと対話するコードだけであることを忘れないでください。OnResponseでの他の処理は、バックグラウンドスレッドで問題なく実行できます。

'MyClass'がフォームやコントロールのようなWindowsオブジェクトでない場合は、あなたが言ったようにInvokeRequiredを持っていません。ただし、InvokeRequiredは必要ありません。UIオブジェクトを表す他のクラスがFTPオブジェクトに応答して何かを実行する必要がある場合、そのUIオブジェクトはInvokeRequiredテストを実行できます。

それがはっきりしていることを願っています!


編集:addl情報

OnReceivedハンドラーは間違いなくFTPクラスにあります。だから私はこのようなことを考えています:

パブリッククラスMyFTPClass{パブリックイベントEventHandlerDataReceived; //UIフォームはこのイベントをサブスクライブできます

 private void OnReceived()
 {
   //so the FTP has returned data
   // Do stuff here that can be on the background thread like saving
   // the file in an appropriate place, or whatever.


   // now trigger the DataReceived event.  Anyone who cares about data being received
   // can subscribe to this and do whatever is appropriate.
   if (DataReceived) DataReceived(this, EventArgs.Empty); 

}

これは大まかな概要です。ただし、基本的な考え方は、バックグラウンドスレッドでローカルに実行できることを実行することです。次に、イベントを通じてUIに通知できます。

于 2009-05-22T18:41:27.343 に答える