簡體   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