0

カスタム オブジェクトを表示するためのコントロールを含むフォームがあります。フォームでは、オブジェクトがサーバーから受信したときにオブジェクトを ToAdd リストに追加するイベント AddObject をサブスクライブします。ToAdd リストから表示リストにオブジェクトをコピーするために 10 秒ごとに実行するようにタイマーをセットアップしました (一度に 1 つずつアイテムをコントロールに追加するよりも、項目をまとめてコントロールに追加する方が効率的でした)。コントロールをフォームに追加したら、ToAdd リストをクリアします。BeginInvoke 内にロックを入れても安全ですか? これを行うより良い方法はありますか?

        private System.Threading.Timer aTimer;
        private readonly Object sync = new Object();
        List<object> ToAdd = new List<object();
        List<object> Display = new List<object();

        private void Init()
        {
           TimerCallback tcb = IntermittentProcessMessages;
           aTimer = new System.Threading.Timer(tcb, null, 1000, 100);
           Server.MessageReceived += AddObject;   
        }

        private void AddObject(object t)
        {
            lock (sync)
            {
                try
                {
                   ToAdd.Add(t);
                }
                finally() {}
            }
         }


        private void IntermittentProcessMessages(object source)
        {
            try
            {
                if (this.IsHandleCreated == false)
                {
                    return;
                }
                this.BeginInvoke((Action)delegate()
                {
                   lock (sync)
                   {
                       if (ToAdd.Count > 0)
                       {
                           ToAdd.ForEach(f => Display.Add(f));
                           ToAdd.Clear();
                       }
                   }
                }
           }
           finally(){}
    }
4

1 に答える 1

1

はい、安全です。技術的には、ロックは ではなく、BeginInvokeから作成された無名関数にありdelegateます。

いくつかのメモ:

  • List<T>AddRangemultiple よりも効率的な方法がありますAdd
    のように使うDisplay.AddRange(ToAdd);
  • のデリゲートは、すぐに返されるIntermittentProcessMessagesため、try-catch の対象外です。BeginInvoke
于 2011-10-03T04:49:44.643 に答える