0

アプリケーションで特定の機能を実行するスレッドを作成しました。実行中に、ユーザーに表示されるアプリケーションのメイン フォームのラベルを更新したいと考えています。

別のスレッドを使用して呼び出している関数を介して文字列データを返そうとしましたが、機能しません。

スレッドを使用したアクティビティの実行中にラベル テキストを更新する解決策があれば教えてください。

class e2ertaData : e2erta1
{
    public void rsData()
    {
        network networkDetails = new network();
        csv csvFile = new csv();
        ftpFile ftpData = new ftpFile();
        //Host Geo Data
        string getIP = networkDetails.GetIP();
        string[] hostData = getIP.Split('~');
        GeoIP geoIPReq = new GeoIP();
        GeoIpData geoIPReqData = new GeoIpData();
        geoIPReqData = geoIPReq.GetMy();
        if (geoIPReqData.KeyValue["Error"].ToString() == "NO")
        {
            //Reading server names from XML file
            XmlDocument thisXmlDoc = new XmlDocument();
            thisXmlDoc.LoadXml(ftpData.getConfigFile("server.xml"));
            XmlNodeList xnList = thisXmlDoc.SelectNodes("/servers/server");
            //updating label in e2erta1

            this.l1.Text = "daaaaaaaaaaa";
            this.l1.Visible = true;
            this.l1.Refresh();
            foreach (XmlNode xn in xnList)
            {
                string rtNote = "";
                string requestedServer = xn["sname"].InnerText;
                string rtGet = networkDetails.GetRT(requestedServer);
                if (rtGet.Contains("Exception"))
                {
                    rtNote = rtGet;
                    //MessageBox.Show(rtNote);
                }
                try
                {
                    var row = new List<string> { rtGet, rtNote };
                    ftpData.addToCSVFile(row);
                }
                catch (Exception c)
                {
                    MessageBox.Show(c.ToString());
                }
            }
        }
        else
        {
            MessageBox.Show("Geo data : " + geoIPReqData.KeyValue["Error"].ToString());
        }
        //return null;
    }
}

ありがとう、

ナビード

4

2 に答える 2

2

あなたのスレッドからこれを使用してください:

this.Invoke((MethodInvoker)delegate
{
    label.Text = "...";
});

編集:

を使用する前にIsHandleCreatedプロパティをテストすることもできますInvoke

private void UpdateLabel(string text)
{
    if (this.IsHandleCreated)
    {
        this.Invoke((MethodInvoker)delegate
        {
            label.Text = text;
        });
    }
    else
    {
        label.Text = text;
    }
}
于 2012-04-25T12:23:01.080 に答える
2

BackgroundWorkerコンポーネントの使用も検討してください。

  1. ToolBox から BackgroundWorker をフォームにドラッグします。
  2. backgroundworker のプロパティ WorkerReportsProgress を true に設定します
  3. バックグラウンド ワーカーのイベント DoWork にサブスクライブする
  4. backgroundworker のイベント ProgressChanged を購読する

DoWork イベント ハンドラー内で、スレッドで行うすべてのことを実行し、ReportProgress メソッドを呼び出して進行状況をフォームに渡します。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // reading server names from XML file        

    for (int i = 0; i < xnList.Count; i++)
    {
        XmlNode xn = xnList[i];
        // process node

        // report percentage to UI thread
        int percentProgress = (i+1)*100/xnList.Count;
        backgroundWorker1.ReportProgress(percentProgress); 
    }
}

ReportProgress イベント ハンドラー内では、ラベルに値を割り当てるだけです。

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    label1.Text = e.ProgressPercentage.ToString();
}

バックグラウンド処理呼び出しを開始するにはbackgroundWorker1.RunWorkerAsync();

更新: コントロールはそれらを作成したスレッド (UI スレッド) からのみ更新できるため、コードは機能していません。そのため、Invoke を使用して UI スレッドで更新機能を実行する必要があります。ここで見つけることができる例と説明。

于 2012-04-25T12:34:26.250 に答える