データロードとフィルタリングスレッドセーフに問題があります。このコードをスレッドセーフにするにはどうすればいいですか
BackgroundWorkerを介してすべてのデータ集団を処理するコントロールの基本クラスの次のコードです。これは、 "this.DataWorker.RunWorkerAsync()"でBackgroundWorkerがビジーであることを示すエラーをスローする傾向があります。
/// <summary>
/// Handles the population of the form data.
/// </summary>
/// <param name="reload">Whether to pull data back from the WebService.</param>
public void Populate(bool reload)
{
if (!this.DataWorker.IsBusy)
{
// Disable the filter options
IvdSession.Instance.FilterManager.SetEnabledState(this.GetType(), false);
// Perform the population
this.DataWorker.RunWorkerAsync(reload);
}
else if (!reload)
{
// If the data worker is busy and this is a not reload, then something bad has happened (i.e. the filter has run during a reload.)
throw new InvalidOperationException("The DataWorker was busy whilst asked to reload.");
}
}
コードが可能な場所に呼ばれています。
private void tmrAutoRefresh_Tick(object sender, EventArgs e)
{
if (!(this.CurrentBody == null))
{
this.CurrentBody.Populate(true);
}
}
そして第二に、いつでもユーザーがドロップダウンリストの番号からフィルタオプションを選択:上
public void Filter()
{
if (!m_BlockFilter)
{
IvdInstance.Main.CurrentBody.FirstRun = true;
IvdInstance.Main.CurrentBody.Populate(false);
}
}
タイマーをまずコントロールがあるフォーム上のタイマによるメインフォームは60秒ごとに実行され、Populateメソッドにtrueを渡します。 truesとしてリロードを渡すと、Webサービスからのデータの新鮮なセットをプルダウンする必要があるとのBackgroundWorkerを伝えます:
void dataWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
if (base.FirstRun)
{
base.CleanListView();
}
if ((bool)e.Argument)
{
byte[] serialized = IvdSession.DataAccess.GetServiceCalls(IvdSession.Instance.Company.Description, IvdSession.Instance.Company.Password, null);
m_DataCollection = new DalCollection<ServiceCallEntity>(serialized);
}
List<ServiceCallEntity> collection = this.ApplyFilter();
base.HandlePopulation<ServiceCallEntity>(collection, e);
}
catch (WebException ex)
{
// Ignore - Thrown when user clicks cancel
}
catch (System.Web.Services.Protocols.SoapException ex)
{
// Log error on server and stay transparent to user
base.LogError(ex);
}
catch (System.Data.SqlClient.SqlException ex)
{
// Inform user that the database is unavailable
base.HandleSystemUnavailable(ex);
}
}
私は正確にフィルタオプションをクリックして管理するときに限り、私は承知しているとして、エラーが発生しますタイマーが人口イベントを発生させるのと同じ時間。私は、Populateメソッドに欠けているもの、つまりロックがあると判断しますが、このインスタンスで正しく使用する方法は不明です。
コードはユーザーの入力に優先されます。ユーザーがフィルタオプションを選択した場合、自動更新がブロックされます。自動更新が発生すると、フィルタオプションは一時的に無効になります。同時に発射された場合は、ユーザーの入力が優先されます(可能な場合)。
誰かが助けてくれることを願っています!
@Groo、Windowsの正確なスペックは分かっていませんが、マルチコアでは同時に2つのことを実行できませんか? –
はい、メソッド*はスレッドセーフにする必要があります。しかしGuiスレッドからGui要素を常に更新する必要があるという規則があります。したがって、Windows.Forms.TimerはイベントハンドラをGuiスレッドキュー(Guiスレッドから呼び出す)に追加して処理を簡素化します。 – Groo
「Windowsの正確な仕様を知らない」と冗談を言っているのは誰ですか? :) – Groo