2017-11-29 9 views
-1

私はBackgroundWorkerから継承したクラスを使用して、リモートサーバー上の特定の処理を行います。このクラスのプロパティを追加して、ジョブの完了に必要な情報を保存しました。例:BackgroundWorkerから派生したクラス内でロック文が必要ですか?

public class GenerateFileWorker : System.ComponentModel.BackgroundWorker 
{ 
    public string LocalFileName { get; set; } 
    public string Username { get; set; } 
    public string Password { get; set; } 

    public GenerateFileWorker() {} 

    public GenerateFileWorker(string username, string password, string localFileName) 
    { 
     Username = username; 
     Password = password; 
     LocalFileName = localFileName; 
    } 
    protected override void OnDoWork(DoWorkEventArgs e) { 
    // ... 
} 

私はlockがクラス外のオブジェクトに安全にアクセスするために必要であることを知っていますが、その内部はどうですか? OnDoWork()の現在のインスタンスのプロパティにアクセスするときに必要ですか?

+2

クラスの内部が別のスレッドでアクセスしようとしているときに、クラス外の誰かがプロパティを操作しようとするとどうなりますか?コードがクラスの内部にあるのか外部にあるのかについては何もしないようにロックを設定する必要があるかどうか – litelite

+0

どうやってそれらのプロパティを使用しますか?あなたはコンストラクタの外にどこにでも書きますか? – Evk

+4

'クラス外のオブジェクトに安全にアクセスするにはロックが必要です。 'いいえ、複数のスレッドから可変状態にアクセスしようとしているときはいつでも' lock'が必要です(または少なくとも共有状態へのアクセスを同期させる多くの方法の1つです)。それはあなたがデータにアクセスするクラスとは何の関係もありません。 – Servy

答えて

1

あなたが継承しているクラスの問題ではありません。複数のスレッドがプロパティやフィールドを同時に読み取ったり変更したりして互いに干渉し合うか、あるスレッドが別のスレッドが何かを更新している間に読み取るかどうかという問題です。そのような競合が発生しないようにするには、lock(またはその他の仕組み)が必要です。 (それは簡潔にするために単純化しすぎです。)

documentationから:

のBackgroundWorkerクラスを使用すると、独立した専用のスレッドで操作を実行することができます。

UIスレッドは、バックグラウンドスレッドを取り消したり、進行状況レポートを取得したり、終了または失敗したことを通知するだけでバックグラウンドスレッドと対話します。プロセス内で使用される変数(状態)には直接アクセスしません。際立っているあなたのクラスで

一つはこれです:

public string LocalFileName { get; set; } 
public string Username { get; set; } 
public string Password { get; set; } 

ものは読み取り/書き込みプロパティされているので、それがバックグラウンドスレッドがそれらを使用している間に、UIスレッドがそれらを更新する可能性があります。私はそれがおそらくあなたの意図ではないと思います。それらのプロパティは書き込み可能である必要がありますか?あるいは、彼らは全く財産である必要もありますか? (プロパティである必要がない場合は、継承する必要がありますか?)

おそらく、これらの値を含む変数をバックグラウンドプロセスの開始時に初期化できます。これらの変数は、バックグラウンドプロセスによって実行されるメソッド内ではプライベートなので、UIスレッドやその他のスレッドがそれらと対話することはできません。

+0

私はこのことをさらに進めているので、プライベートな物件は行く道があるようです。初期化の外でそれらを変更する必要はほとんどありません。 –

関連する問題