如何使用 Windows 窗体 C# 应用程序在第二个线程中检索信息

本文关键字:线程 第二个 检索 信息 应用程序 何使用 Windows 窗体 | 更新日期: 2023-09-27 18:35:43

我有一个通常的C# Windows窗体应用程序,其中包含一个窗体和多个文本框/标签,该应用程序在自己的线程中运行(我如何理解)。(赢 7 64/VS 2008/净 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) 的主线程中。所以我必须在那里获取检索到的信息。

如何使用 Windows 窗体 C# 应用程序在第二个线程中检索信息

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

看看这里如何做到这一点

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

切勿从另一个线程上运行的代码访问 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 对象)。

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

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

我收到的三个答案使我无处可去或没有奏效,所以我自己在很久以后才发现:我使用后台工作者控件来实现我想要的东西。在后台工作者的"已完成"事件中,我可以访问 UI 并将信息传输到附加到我的应用程序的表单中。如果我的 UI 被锁定为第二个线程,这对我有什么帮助,所以 Backgroundworker 最适合我去自我解释。