在哪里放置 BackgroundWorker
Where to place the BackgroundWorker
我有一个 class 收集有关机器的信息(这是一个示例 - 总共 GetInfo() 可能需要几分钟才能 运行):
public class Scanner
{
public void GetInfo()
{
this.Name = GetName();
this.OS = GetOS();
}
public string Name { get; set; }
public string OS { get; set; }
public string Status { get; set; }
private string GetName() { this.Status = "Getting computer name"; /*More operations*/ }
private string GetOS() { this.Status = "Getting OS"; /*More operations*/ }
}
这是由需要向用户提供状态反馈的表单调用的。
TextBox1.Text = scanner.Status;
我的问题是,要实现这一点,实现线程以使应用程序保持响应的最佳方式是什么?
我在表单中有一个 BackgroundWorker 运行ning 并调用 GetName()、GetOS() 等本身并且工作正常,但代码不是很可重复 - 我想要保持低维护在 class 中保留 GetInfo() 方法,因此如果我需要 运行 从其他地方进行扫描,那么只有一段代码知道如何进行。
我可以将 BackgroundWorker 移动到 GetInfo(),但是表单如何能够在不执行循环和锁定 UI 的情况下检查状态 属性?
也许有一个 BackgroundWorker 形式为 运行 GetInfo(),然后 运行 另一个 Worker 将检查状态并在检测到更改时更新表单?
这是我对线程处理的第一次正确尝试,我无法理解我认为这是一项相当常见的任务,因此我们将不胜感激。
注意:我也很乐意接受有关其他实现 Status 的方法的建议 属性 - 希望您明白我正在努力实现的目标。
/编辑:一些说明。
Scanner.GetInfo() 将被手动调用,例如在单击表单按钮时。 GetInfo() 然后会在收集信息时开始填充对象属性,可能需要 5 分钟才能完成。
我需要能够让用户了解其最新状态,而我能想到的唯一方法(以我目前的知识)是让 GetInfo() 更新 'Scanner.Status' 属性,然后表单可以在 interval/within 循环检查并在它更改时更新 UI。
如何使用 INotifyPropertyChanged
和 class 中的线程,如下所示:
public class Scanner : INotifyPropertyChanged
{
private string _Name, _OS;
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get
{
return _Name;
}
set
{
if (value != _Name)
{
_Name = value;
NotifyPropertyChanged("Name");
}
}
}
public string OS
{
get
{
return _OS;
}
set
{
if (value != _OS)
{
_OS = value;
NotifyPropertyChanged("OS");
}
}
}
public void GetInfo()
{
_Name = string.Empty;
_OS = string.Empty;
new Thread(() => this.Name = GetName()).Start();
new Thread(() => this.OS = GetOS()).Start();
}
private void NotifyPropertyChanged(string pName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
}
private string GetName()
{
return "long name operation here";
}
private string GetOS()
{
return "long OS operation here";
}
}
然后在您的表单中,您可以使用以下内容:
Scanner m_Scanner = new Scanner();
public void Main()
{
m_Scanner.PropertyChanged += UpdateGUI;
m_Scanner.GetInfo();
}
private void UpdateGUI(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "OS")
txtOs.Text = m_Scanner.OS;
else if (e.PropertyName == "Name")
txtName.Text = m_Scanner.Name;
}
我有一个 class 收集有关机器的信息(这是一个示例 - 总共 GetInfo() 可能需要几分钟才能 运行):
public class Scanner
{
public void GetInfo()
{
this.Name = GetName();
this.OS = GetOS();
}
public string Name { get; set; }
public string OS { get; set; }
public string Status { get; set; }
private string GetName() { this.Status = "Getting computer name"; /*More operations*/ }
private string GetOS() { this.Status = "Getting OS"; /*More operations*/ }
}
这是由需要向用户提供状态反馈的表单调用的。
TextBox1.Text = scanner.Status;
我的问题是,要实现这一点,实现线程以使应用程序保持响应的最佳方式是什么?
我在表单中有一个 BackgroundWorker 运行ning 并调用 GetName()、GetOS() 等本身并且工作正常,但代码不是很可重复 - 我想要保持低维护在 class 中保留 GetInfo() 方法,因此如果我需要 运行 从其他地方进行扫描,那么只有一段代码知道如何进行。
我可以将 BackgroundWorker 移动到 GetInfo(),但是表单如何能够在不执行循环和锁定 UI 的情况下检查状态 属性?
也许有一个 BackgroundWorker 形式为 运行 GetInfo(),然后 运行 另一个 Worker 将检查状态并在检测到更改时更新表单?
这是我对线程处理的第一次正确尝试,我无法理解我认为这是一项相当常见的任务,因此我们将不胜感激。
注意:我也很乐意接受有关其他实现 Status 的方法的建议 属性 - 希望您明白我正在努力实现的目标。
/编辑:一些说明。
Scanner.GetInfo() 将被手动调用,例如在单击表单按钮时。 GetInfo() 然后会在收集信息时开始填充对象属性,可能需要 5 分钟才能完成。
我需要能够让用户了解其最新状态,而我能想到的唯一方法(以我目前的知识)是让 GetInfo() 更新 'Scanner.Status' 属性,然后表单可以在 interval/within 循环检查并在它更改时更新 UI。
如何使用 INotifyPropertyChanged
和 class 中的线程,如下所示:
public class Scanner : INotifyPropertyChanged
{
private string _Name, _OS;
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get
{
return _Name;
}
set
{
if (value != _Name)
{
_Name = value;
NotifyPropertyChanged("Name");
}
}
}
public string OS
{
get
{
return _OS;
}
set
{
if (value != _OS)
{
_OS = value;
NotifyPropertyChanged("OS");
}
}
}
public void GetInfo()
{
_Name = string.Empty;
_OS = string.Empty;
new Thread(() => this.Name = GetName()).Start();
new Thread(() => this.OS = GetOS()).Start();
}
private void NotifyPropertyChanged(string pName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
}
private string GetName()
{
return "long name operation here";
}
private string GetOS()
{
return "long OS operation here";
}
}
然后在您的表单中,您可以使用以下内容:
Scanner m_Scanner = new Scanner();
public void Main()
{
m_Scanner.PropertyChanged += UpdateGUI;
m_Scanner.GetInfo();
}
private void UpdateGUI(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "OS")
txtOs.Text = m_Scanner.OS;
else if (e.PropertyName == "Name")
txtName.Text = m_Scanner.Name;
}