【问题标题】:How to retrieve information in a second thread with a Windows Forms C# Application如何使用 Windows 窗体 C# 应用程序在第二个线程中检索信息
【发布时间】:2013-10-26 03:01:15
【问题描述】:

我有一个普通的C# Windows 窗体应用程序,它有一个窗体和几个文本框/标签,它在自己的线程中运行(我的理解)。 (Win 7 64 / VS 2008 / Net 2)。

现在我想在我的基础应用程序停留在第一个线程中时启动第二个线程。 第二个线程将检索一些系统信息并将其输入到标签中,而我的用户仍然能够填写文本框,而信息将由第二个线程检索。因此,据我了解,优势在于,用户不必等到检索信息完成,并且主应用程序不会在那段时间内挂起。

假设我希望这段代码在第二个线程中执行,该线程从 Form_Shown 事件开始:

 Label1.Text = GetInternetIP();
 try
 {
 Label2.Text = System.Net.Dns.GetHostEntry(Label1.Text).HostName.ToString();
 }
 catch{MessageBox.Show("Fatal Error."); Process.Start("shutdown.exe", "-r -t 2"); this.Activate(); SendKeys.Send("%{F4}");}

如果能详细说明如何设置“新线程”,我将不胜感激。我是新手,但我想学习新知识并优化(加速)我的第一个应用程序。

Label1 和 Label2 位于主窗体 (Form1) 上的主线程中。所以我必须在那里获取检索到的信息。

【问题讨论】:

    标签: c# multithreading winforms operating-system


    【解决方案1】:

    在处理 Windows 窗体时,UI 只能在一个线程上运行,然后它将创建后台线程,后台线程检索数据,然后将其传递给单个 UI 线程。这也是它在 WPF 中的工作方式。

    在此处查看如何执行此操作

    http://msdn.microsoft.com/en-us/magazine/cc300429.aspx

    【讨论】:

      【解决方案2】:

      您永远不应该从另一个线程上运行的代码访问您的 UI 组件。事实上,你不应该从多个线程访问 任何东西,除非这些东西是明确的线程安全的(或者你以线程安全的方式访问它们)。

      在您的示例中,您是说要获取需要一些时间的信息。在您的情况下,您想要的编程模型是让您的主线程调用一个异步函数来检索该信息,并且它应该在信息准备好时向您的主线程发出信号。

      在 C# 中实现多线程编程有很多不同的方法,但这里有一个示例:

      public Task<IPAddress> GetInternetIP()
      {
          return Task.Factory.StartNew(() =>
          {
              IPAddress ip;
      
              // do some work to get the IPAddress
      
              return ip;
          });
      }
      
      private void Form_Load(object sender, EventArgs e)
      {
          GetInternetIP().ContinueWith(ip =>
          {
              Label1.Text = ip.ToString();
          }, TaskScheduler.FromCurrentSynchronizationContext());
      }
      

      在这种情况下,您正在执行System.Threading.Tasks.Task,它将为您处理多线程。你告诉它继续使用当前线程上的方法执行。该方法将传递任务的返回值(在本例中为 IPAddress 对象)。

      【讨论】:

        【解决方案3】:

        要从后台线程访问主线程上的用户控件,您只需对要填充的控件使用 BeginInvoke。这篇文章充分解释了如何做到这一点以及这样做的来龙去脉。

        http://weblogs.asp.net/justin_rogers/pages/126345.aspx

        【讨论】:

          【解决方案4】:

          我收到的三个答案让我无处可去或没有工作,所以我后来自己发现了:我使用 Backgroundworker-Control 来实现我想要的。在 Backgroundworker 的“已完成”事件中,我可以访问 UI 并将信息传输到附加到我的应用程序的表单中。如果我的 UI 针对第二个线程被锁定,那么对我的第二个线程有什么帮助,所以 Backgroundworker 是我最好的选择和自我解释。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-07-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-23
            • 2017-04-02
            • 1970-01-01
            相关资源
            最近更新 更多