クラスにスレッド/バックグラウンドワーカーを配置するのは「間違った」/悪い設計ですか?


15

Excel(C#および.Net 4)から読み取るクラスがあり、そのクラスには、UIの応答性を維持しながらExcelからデータをロードするバックグラウンドワーカーがあります。私の質問は次のとおりです。クラスにバックグラウンドワーカーを配置するのは悪い設計ですか。クラスなしでクラスを作成し、バックグラウンドワーカーを使用してそのクラスを操作する必要がありますか?この方法でクラスを作成することに関する問題は実際にはありませんが、それでも私は初心者なので、先に進む前に確認することを考えました。

私のコードが機能するので、これはスタックオーバーフローではないはずだと思うので、この質問がここで関連することを願っています。これは単なる設計上の問題です。


3
なぜ間違っていると思うのですか?
-Alb

1
@Alb-言うのは難しいです。私のコードは機能し、私のニーズを満たしますが、オープンソースを作成するプロジェクトでこれを使用することを計画しています。私のコードが「機能する」だけでなく、実際にうまく設計されていることを確認したいと思います。
ジェッティ

回答:


21

クラスなしでクラスを作成し、バックグラウンドワーカーを使用してそのクラスを操作する必要がありますか?

はい、そうすべきです。そして、その理由をお話しします-あなたは単一責任原則に違反しています。excel docにアクセスするクラスとexcel doc にアクセスする方法を密に結合することにより、「コントローラー」コード(これを使用するコード)が別の方法でそれを実行する機能を排除します。どれほど違うのでしょうか?コントローラーコードに時間がかかる2つの操作があり、それらを順次にしたい場合はどうなりますか?コントローラにスレッド処理機能を許可した場合、1つのスレッドで両方の長時間実行タスクを一緒に実行できます。非UIコンテキストからExcelドキュメントにアクセスし、スレッド化する必要がない場合はどうなりますか?

スレッド化の責任を呼び出し側に移すことにより、コードの柔軟性を高め、再利用性を高めることができます。


2
+1質問された実際の質問に回答し、適切に回答した場合。
アダムリア

+1-ネミありがとう。あなたは私の質問スポットに答えました、私はそれを感謝します。それをクラスから引き出して、新しいクラスに入れます。ありがとうございます!
ジェッティ

@Nemi-したがって、同期ロードを行う別のメソッドを作成してから非同期メソッドを使用することは受け入れられますか?または、1つの同期ロードメソッドを使用してからそこから進む方が良いでしょうか?
ジェッティ

1
個人的には、syncメソッドとasyncメソッドはありません。あなたはまだ責任を結合しています。私はこの正確な問題に何度も取り組んできました。私がしたことは、SwingWorkerをモデルにしたTaskControllerを作成しましたが、アプリ用の特定のコードがありました。TaskControllerは、プログレスバーの更新、マウスカーソルの変更などの処理を行いました。呼び出しを行うために常にTaskControllerを作成する必要がある定型コードのように見えるかもしれませんが、最終的にコードはより堅牢で保守性が高くなります。
ネミ

おかげでネミ!あなたが私の質問に間違いなく答えて、正しい方向に私を指し示したので、私はあなたにもう一度賛成できたらと思います。ありがとうございました!!
ジェッティ

3

UI操作をバックグラウンドタスクとは別のスレッドで動作させるのは良い設計です。そうしないと、アプリケーションがビジーのときにUIが応答しなくなります。

バックグラウンドスレッドで動作する部分を独自のクラスに分離できる場合、コードはよりクリーンになります。


1
彼の質問をどのように読んだかから、彼はこの点を理解するのに問題はない。
ネミ

私の質問が誤読されてすみません。UIとバックグラウンドタスクを分離するのは良い設計であることを知っています(必要でない場合、テスト用のExcelファイルは8k行を超えているため、プログラムが応答しなくなったように見えます)。私の質問は基本的に、スレッドとExcelクラスを緊密に結合することです。
ジェッティ

0

別のクラスを使用して、バックグラウンドタスクからUIを分離します。そうすることで、懸念の分離が促進されます。UIコードとビジネスロジックを混在させないでください。


明確にするために、私のクラスはUIに触れません。必要に応じてUIを更新するために使用しているものを許可する2つのイベントがありますが、クラス自体はUIに触れません。
ジェッティ

0

BackgroundWorkersについて思い出すと、進行状況の更新をUIに送信する機能など、多くの便利なメソッドが提供されているということです。ただし、別のクラスからは使用できないというルールはありません。

また、アイテムを特定の順序で処理する必要のない反復を行う場合は、代わりにThreadPoolの使用を検討してください(または.NET 4を使用している場合はTask Parallel Libraryを使用してください)。


お返事をありがとうございます。進行状況をトリガーする2つのイベントをクラスで作成し(基本的には、BackgroundWorkerはprivateであるため、BackgroundWorker progressイベントをラップします)、進行状況をUI(進行状況バー)に送信します。
ジェッティ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.