从 BackgroundWorker 派生的 class 中是否需要锁定语句?

Is a lock statement needed within a class derived from BackgroundWorker?

我有一个 class 继承自 BackgroundWorker 以在远程服务器上执行一些特定的操作。我为此 class 添加了属性以存储完成作业所需的信息。示例:

 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 才能安全地访问 class 之外的对象,但是在 class 内部呢?在 OnDoWork() 中访问当前实例的属性时是否需要它?

这不是您从 class 继承什么的问题。这是一个问题,即多个线程是否可以同时读取或修改属性或字段,以便它们相互干扰,或者一个线程读取而另一个线程正在更新某些内容。那时您需要 lock (或其他某种机制)来确保不会发生此类冲突。 (为简洁起见过于简单化了。)

来自documentation

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread.

想法是 UI 线程仅通过取消后台线程、从后台线程获取进度报告或收到已完成或失败的通知来与后台线程交互。它不直接访问流程中使用的变量(状态)。

在您的 class 中,有一点很突出:

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

因为这些是 read/write 属性,所以 UI 线程可能会在后台线程使用它们时更新它们。我想这可能不是你的意图。这些属性是否需要可写?或者它们甚至需要是属性吗? (如果不需要是属性,是否需要继承?)

也许您可以在后台进程开始时初始化包含这些值的变量。现在这些变量在后台进程执行的方法中是私有的,这意味着 UI 线程或任何其他线程不可能与它们交互。