Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在哪里放置后台工作人员_C#_Backgroundworker - Fatal编程技术网

C# 在哪里放置后台工作人员

C# 在哪里放置后台工作人员,c#,backgroundworker,C#,Backgroundworker,我有一个类可以收集有关机器的信息(这是一个示例-总的来说,GetInfo()可能需要几分钟才能运行): 这由需要向用户提供状态反馈的表单调用 TextBox1.Text = scanner.Status; 我的问题是,要实现这一点,实现线程的最佳方法是什么,以使应用程序保持响应 我有一个BackgroundWorker运行在表单中,调用GetName()、GetOS()等,这很好,但是代码不是很容易重复-为了保持低维护,我想在类中保留一个GetInfo()方法,因此如果我需要从其他地方运行扫描

我有一个类可以收集有关机器的信息(这是一个示例-总的来说,GetInfo()可能需要几分钟才能运行):

这由需要向用户提供状态反馈的表单调用

TextBox1.Text = scanner.Status;
我的问题是,要实现这一点,实现线程的最佳方法是什么,以使应用程序保持响应

我有一个BackgroundWorker运行在表单中,调用GetName()、GetOS()等,这很好,但是代码不是很容易重复-为了保持低维护,我想在类中保留一个GetInfo()方法,因此如果我需要从其他地方运行扫描,只有一段代码知道如何执行

我可以将BackgroundWorker移到GetInfo(),但是表单如何能够在不执行循环和锁定UI的情况下检查Status属性呢

也许让后台工作人员在表单中运行GetInfo(),然后运行另一个工作人员,该工作人员将检查状态并在检测到更改时更新表单

这是我第一次正确地使用线程,我想这是一项相当常见的任务,所以我无法理解这一点,因此,如果有任何帮助,我将不胜感激

注意:我也很乐意接受关于实现Status属性的其他方法的建议——希望你能得到我想要实现的东西

/编辑:一些澄清

将手动调用Scanner.GetInfo(),例如在表单按钮上单击。然后,GetInfo()将在收集信息时开始填充对象属性,可能需要5分钟才能完成


我需要能够让用户保持其状态的最新状态,我能想到的唯一方法(以我目前的知识)是让GetInfo()更新“Scanner.status”属性,表单可以在循环中每隔一段时间检查一次,并在更改时更新UI。

如何使用
INotifyPropertyChanged
和类中的线程,如下所示:

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;
}

没有。使用
async/await
和任务。改为运行。使用
wait Task.Delay()编写循环是很简单的;var scanner=wait Task.Run(MyPollingFunction);textBox1.Text=scanner.Status在它的主体中,或者创建一个带有
异步
回调的计时器。是什么触发了
GetInfo
的调用?或者你希望它什么时候发生?以一定的间隔循环?或者你手动触发它?这是在WPF/MVVM环境中使用的吗?看看Stephen C的博客:如果你想循环触发它,可能只是一个
计时器
就可以解决你的问题鉴于上面的回答,这就是我要做的。我无法访问txtName(在您的示例中),因为它是一个跨线程操作,但我将看看我能想出什么解决方法。在这里查看有关跨线程异常的信息:
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;
}