2009-06-18 8 views
4

私は2つのリストボックスを持っています.1つはマスター、もう1つは子です。マスター上でインデックスが変更されると、子リストボックスはマスタに関するレコードで適切に埋められます。あるマスターがすべてのレコードを取得するのに長い時間がかかり、レコードの取得が完了する前に、ユーザーが入力する時間がかかりにくい別のマスターをクリックすると、問題が発生しています。何が起こるのかは、最終的に、ユーザーがそのマスターにもういなくても、子リストボックスを長く取っていたマスターがいっぱいになります。winformsのワーカースレッドをキャンセルする

私は、塗りつぶしにBackgroundWorkerスレッドを使用しています。

bw_LoadAll.DoWork += new DoWorkEventHandler(bg_LoadAllWork); 
bw_LoadAll.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_LoadAllWorkCompleted); 
bw_LoadAll.WorkerSupportsCancellation = true; 

私はマスターのためのSelectedIndexChangedイベントに加入し、私がtrueにキャンセル等しいを設定します。ここでは

bw_LoadAll.CancelAsync(); 

は、DoWorkメソッドのコードです:

List<object> s = Repository.Instance().LoadAll(); 
if (!bw_LoadAll.CancellationPending) { 
    e.Result = s; 
} else { 
    e.Cancel = true; 
} 

だがについて何らかの理由で、完了した作業者のコードが引き続き呼び出されます。作業者が完了したコードは次のとおりです。

このスレッドの返信をキャンセルするには何か他に何かありますか?

答えて

5

あなたの方法、bg_LoadAllWorkは、のように定義する必要があります。bg_LoadAllWorkの内部

void bg_LoadAllWork(object sender, DoWorkEventArgs e) 
{ 
    // Do your work here... 
} 

、あなたがe.CancellationPendingをチェックする必要があり、それが本当ならば、この最後の部分が重要であるe.Cancel = true;

を設定する - 場合あなたはe.Cancelを決して決して決してあなたの "e.Cancelled"は決して真とはなりません。 CancelAsyncを呼び出すと、実際には何もキャンセルされません。つまり、バックグラウンドワークがキャンセルされるようにリクエストすることです。キャンセルするにはロジックを配置する必要があります。

+0

CancellationPendingは、BackgroundWorkerではなく、DoWorkEventArgsに公開されています。この例ではのパラメータになります。 – Sherlock

0

do_work関数のCodeProjectからワーカースレッドでCancellationPendingを確認し、DoWorkEventArgs.Cancel変数をtrueに設定する必要があります。

+0

マスターアイテムをクリックするのに時間がかかる場合は機能しますが、クリックしてから別のアイテムをクリックすると、時間通りに設定されていないようです。私は作業メソッドで何をしているのかを示すコードを更新します。 – Josh

0

あなたがbw_LoadAll.CancelAsyncを呼び出すときLoadAllWorkがbw_LoadAll.CancelationPendingをチェックしない限り、それは私がのBackgroundWorkerを使用しましたので、しばらくして、私の記憶があります場合は、あなたのLoadAllWork方法の実際の中絶はありませんです。 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspxによって確認

「CancelAsyncは保留中のバックグラウンド操作を終了する要求を提出し、trueにCancellationPendingプロパティを設定します

あなたがCancelAsyncを呼び出すと、あなたの労働者の方法は、その実行とを停止する機会を持っています。作業者コードは定期的にCancellationPendingプロパティをチェックして、trueに設定されているかどうかを確認する必要があります。あなたがbw_LoadAll.CancelAsync()を呼び出すとき

だから、あなたのSelectedIndexChangedイベントハンドラで、それは本当のbw_LoadAll.CancelationPendingを設定していますが、それは実際にLoadAllWork方法を中止いません。スローローダーはまだ終了します。

関連する問題