問題:
私は、時間のかかる操作のために、キャンセルボタン付きのフォーム (WinForm) にプログレスバーを表示することになっているアプリケーションに取り組んでいます。したがって、明らかに私は BackgroundWorker スレッドを使用しています。以下は、私が達成しようとしていることを大まかにシミュレートするコードです。
namespace WindowsFormsApplication1
{
public delegate void SomeDelegateHandler();
public partial class Form1 : Form
{
public event SomeDelegateHandler DoSomeAction;
BackgroundWorker bgWorker;
public Form1()
{
InitializeComponent();
bgWorker = new BackgroundWorker();
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
}
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
//Some logic code here.
for (int i = 0; i < 100; i++)
{
DoSomeAction();
}
}
private void Form1_Shown(object sender, EventArgs e)
{
if (DoSomeAction != null)
bgWorker.RunWorkerAsync();
else throw new EventNotSubscribedException();//Is this a valid style??
}
}
public class EventNotSubscribedException : ApplicationException
{
//Some custom code here
}
}
私の解決策
上記のコードに従って、フォームがユーザーに表示されるとすぐに (OnShown イベント)、backgroundworker スレッドを開始します。これは、ユーザーがこれを行うためにアクションを開始する必要がないためです。そのため、onshown は時間のかかる操作ジョブを実行します。しかし、問題は、上で示したように、時間のかかる主なジョブが他のクラス/コンポーネントで実行されることです。そこでは、それも厳密に制限されています(レガシーコード:リファクタリングできません)。したがって、このフォームを起動するレガシ コード クラスのイベント DoSomeAction にサブスクライブしました。
疑問/質問:
上記のように例外をスローすることは有効ですか? (以下の私の理由を読んでください)。
理由:
OnShown イベントは、イベント ハンドラー オブジェクトの null をチェックします。これは、このフォームを使用可能にするには、サブスクライバー (使用コード) がイベントをサブスクライブする必要があるためです。そうでない場合、フォームは表示されるだけでまったく通知されず、使用コードはなぜそうなっているのかわからない可能性があります。使用法コードは、ボタン クリック イベントと同様に、イベントへのサブスクライブがオプションであると想定する場合があります。
私の投稿が明確でわかりやすいことを願っています。
ありがとう & 幸せなコーディング、Zen :)