0

TreeViewを含む単純なWindowsFormアプリケーションがあります。初期化時-TreeViewはデフォルトのimageIndexesを使用してXMLから構築しています。私のTreeViewはサーバー名で構成されています。タグ要素に、ホストとIPで構成される辞書を入れます。初期化後、メソッドを呼び出します。サーバーがtimedOutの場合は、imageIndexを変更します。非ブロックメインスレッド(GUI)であるBackgroundWorkerでこのメソッドを呼び出す必要があります。このメソッドを毎分実行する予定です。この方法は次のとおりです。

    private void checkServersTree()
    {
        TreeNodeCollection rootNodes = treeViewSrv.Nodes;
        TreeNodeCollection childNodes;
        PingServers ps = new PingServers();
        for (int i = 0; i < rootNodes.Count; i++)
        {
            childNodes = treeViewSrv.Nodes[i].Nodes;
            treeViewSrv.Nodes[i].Text += string.Format(" ({0})", childNodes.Count);
            int downServers = 0;
            foreach (TreeNode tNode in childNodes)
            {
                if (tNode.Tag != null)
                {
                    Dictionary<string, string> dicParams = tNode.Tag as Dictionary<string, string>;

                    if (!ps.getServerStatus(dicParams["host"], dicParams["ip"]))
                    {
                        tNode.ImageIndex = 1;   //red
                        rootNodes[i].ImageIndex = 2;   //yellow
                        downServers++;
                    }
                }
            }

            if(downServers == childNodes.Count)
                rootNodes[i].ImageIndex = 4;   //fatal red
        }
    }

前もって感謝します!


ご回答ありがとうございます!ここに書く前に、InvokeとBeginInvokeについて読みました。しかし、私はこの問題を解決することはできません-TreeViewImageIndexesを変更する非同期スレッドを実行します。私はあなたのリンクに行き、コードを書きました(以下)が、GUIはブロックされたままです。私は何が間違っているのですか?

namespace CCCServers
{
    public partial class CCCServers : Form
    {
        public delegate void checkSrvDelegate();
        public checkSrvDelegate myDelegate;
        private Thread myThread;

        public CCCServers()
        {
            InitializeComponent();

            TreeFromXML tfXML = new TreeFromXML(treeViewSrv, "../../Servers.xml");
            tfXML.initTreeNodesFromXML();

            treeViewSrv.ExpandAll();

            //checkServersTree();
            myDelegate = new checkSrvDelegate(checkServersTree);
        }

        private void checkServersTree()
        {
            TreeNodeCollection rootNodes = treeViewSrv.Nodes;
            TreeNodeCollection childNodes;
            PingServers ps = new PingServers();
            for (int i = 0; i < rootNodes.Count; i++)
            {
                childNodes = treeViewSrv.Nodes[i].Nodes;
                treeViewSrv.Nodes[i].Text += string.Format(" ({0})", childNodes.Count);
                int downServers = 0;
                foreach (TreeNode tNode in childNodes)
                {
                    if (tNode.Tag != null)
                    {
                        Dictionary<string, string> dicParams = tNode.Tag as Dictionary<string, string>;

                        if (!ps.getServerStatus(dicParams["host"], dicParams["ip"]))
                        {
                            tNode.ImageIndex = 1;   //red
                            rootNodes[i].ImageIndex = 2;   //yellow
                            downServers++;
                        }
                    }
                }

                if(downServers == childNodes.Count)
                    rootNodes[i].ImageIndex = 4;   //fatal red
            }
        }

        private void btnRDP_Click(object sender, EventArgs e)
        {
            myThread = new Thread(new ThreadStart(threadFunction));
            myThread.Start();
        }

        private void threadFunction()
        {
            MyThreadClass myThreadClassObject = new MyThreadClass(this);
            myThreadClassObject.Run();
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            MessageBox.Show(e.Node.Text, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void treeViewSrv_AfterSelect(object sender, TreeViewEventArgs e)
        {
            e.Node.SelectedImageIndex = e.Node.ImageIndex;  //Что бы иконка не менялась при выборе узла
        }
    }

    //***************************************************************************

    public class MyThreadClass
    {
        CCCServers cccSrv;
        public MyThreadClass(CCCServers myForm)
        {
            cccSrv = myForm;
        }

        public void Run()
        {
            cccSrv.Invoke(cccSrv.myDelegate);
        }
    }
}
4

2 に答える 2

0

ウィンドウハンドルを作成したスレッドでユーザーインターフェイスメソッドを実行するには、フォームのInvokeメソッドを使用する必要があります。例えば

Invoke((Action) checkServersTree);
于 2013-03-06T21:56:27.877 に答える
0

私は自分の問題を解決します。特別な場所にコードを挿入した後、これはメインスレッドで呼び出されていることに気付きました。したがって、時間をかけて気付かないすべての人Debug.WriteLine(String.Format("<<<<<<<< This is {0} thread", Thread.CurrentThread.ManagedThreadId));が。以下のコードを参照してください。Control.InvokeControl.Invoke

private delegate void setServersCountDelegate(int idx, int cnt);
private delegate void setChldNodeImgIndexDelegate(TreeNode tNode, int imgIdx);

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    testBuildTree();
}

private void testBuildTree()
{
    Thread.CurrentThread.Name = "CheckServers";
    Debug.WriteLine(String.Format("|||||||||| This is {0} thread", Thread.CurrentThread.ManagedThreadId));
    changeImgIndex();
}

private void changeImgIndex()
{
    Debug.WriteLine(String.Format("--------- This is {0} thread", Thread.CurrentThread.ManagedThreadId));
    TreeNodeCollection rootNodes = treeViewSrv.Nodes;
    TreeNodeCollection childNodes;

    for (int i = 0; i < rootNodes.Count; i++)
    {
        childNodes = treeViewSrv.Nodes[i].Nodes;
        //treeViewSrv.Nodes[i].Text += string.Format(" ({0})", childNodes.Count);
        treeViewSrv.Invoke(new setServersCountDelegate(setServersCount), new object[] { i, childNodes.Count });
        int downServers = 0;
        foreach (TreeNode tNode in childNodes)
        {
            if (tNode.Tag != null)
            {
                Dictionary<string, string> dicParams = tNode.Tag as Dictionary<string, string>;

                if (!getServerStatus(dicParams["host"], dicParams["ip"]))
                {
                    Debug.WriteLine(String.Format("<<<<<<<< This is {0} thread", Thread.CurrentThread.ManagedThreadId));
                    //tNode.ImageIndex = 1;   //red
                    treeViewSrv.Invoke(new setChldNodeImgIndexDelegate(setChldNodeImgIndex), new object[] { tNode, 1 });    //red
                    //rootNodes[i].ImageIndex = 2;   //yellow
                    treeViewSrv.Invoke(new setChldNodeImgIndexDelegate(setChldNodeImgIndex), new object[] { rootNodes[i], 2 }); //yellow
                    downServers++;
                }
            }
        }

        if (downServers == childNodes.Count)
        {
            //rootNodes[i].ImageIndex = 4;   //fatal red
            treeViewSrv.Invoke(new setChldNodeImgIndexDelegate(setChldNodeImgIndex), new object[] { rootNodes[i], 4 });
        }
    }
}

private void setServersCount(int idx, int cnt)
{
    string[] spltNodeText = treeViewSrv.Nodes[idx].Text.Split(' ');
    treeViewSrv.Nodes[idx].Text = string.Format("{0} ({1})", spltNodeText[0], cnt);
}

private void setChldNodeImgIndex(TreeNode tNode, int imgIdx)
{
    tNode.ImageIndex = imgIdx;
}
于 2013-03-12T18:41:53.657 に答える