繁体   English   中英

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

[英]How to retrieve information in a second thread with a Windows Forms C# Application

我有一个普通的C#Windows Forms应用程序,其中包含一个窗体和几个TextBoxes / Label ,它们在自己的线程中运行(据我所知)。 (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)的主线程中。 所以我必须在那里获取检索到的信息。

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

看看这里如何做到这一点

http://msdn.microsoft.com/zh-CN/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

我收到的三个答案使我无所适从,或者没有用,所以我很晚才发现:我使用Backgroundworker-Control实现了我想要的。 在Backgroundworker的“已完成”事件中,我可以访问UI并将信息传输到附加到我的应用程序的表单中。 如果UI被第二个线程锁定,那么对我有帮助的第二个线程是什么,因此Backgroundworker是我最好的自我解释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM