0

我有一个普通的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) 上的主线程中。所以我必须在那里获取检索到的信息。

4

4 回答 4

0

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

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

于 2013-10-19T18:46:10.757 回答
0

你永远不应该从另一个线程上运行的代码访问你的 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 对象)。

于 2013-10-17T15:05:28.140 回答
0

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

于 2013-12-08T02:43:23.977 回答
0

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

看看这里如何做到这一点

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

于 2013-10-17T14:44:29.787 回答