Exemplo n.º 1
0
        private void SendWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var work = sender as BackgroundWorker;

            if (work == null)
            {
                return;
            }
            while (!work.CancellationPending)
            {
                if (messageList.Count == 0 && sendableList.Count == 0)
                {
                    notEmptyWaiter.WaitOne();
                }

                Message message = null;
                if (messageList.Count > 0)
                {
                    lock (locker) message = messageList.Dequeue();
                    SendImpl(message);
                }
                else
                {
                    //这个要在count判断之前做,因为remove之后count可能=0了
                    sendableList.RemoveAll(sendable => sendable == null || sendable.IsPostCompleted || sendable.TransferState == TransferState.Canceled || sendable.TransferState == TransferState.Error);
                    if (sendableList.Count > 0)
                    {
                        //如果在两次循环之间,一个sendable的状态被改变了,不需要再发送(例如取消,或者对方发现这个文件已经存在)
                        ISendable selectedItem = null;
                        lock (locker)
                        {
                            //计算优先级,除了根据splittable的Priority之外,还要根据上次的处理时间,
                            //这样的话,才能做到如果有几个任务同时进行(发文件,收文件,浏览,同步)的时候,每个任务都能得到响应。
                            //但一个splittable内部不考虑上次处理时间。因为同一批次的文件,并行发送没有意义
                            sendableList.Sort(SendableComparer <ISendable> .Instance);
                            selectedItem = sendableList[0];
                        }
                        try
                        {
                            message = selectedItem.GetNextMessage();
                        }
                        catch (Exception ex)
                        {
                            //产生了一个错误消息。稍后会处理。
                        }
                        //ToMessage或者GetNextMessage可能发生异常。例如文件读取错误
                        if (message != null)
                        {
#if DEBUG
                            if (message is ThumbnailResponseMessage)
                            {
                                var trm = selectedItem as ThumbnailResponseMessage;
                                if (trm != null)
                                {
                                    Trace.WriteLine("name=" + trm.Name + " id=" + trm.ID + " len=" + trm.Length);
                                }
                            }
                            if (message is ConversationMessage)
                            {
                                var cm = message as ConversationMessage;
                                if (cm == null || cm.ConversationID == null)
                                {
                                    throw new Exception("Conversation Message的会话ID没有设置");
                                }
                            }
#endif
                            SendImpl(message);
                        }
                        else
                        {
#if DEBUG
                            var itemState = selectedItem.TransferState;
                            if (itemState != TransferState.Error && !selectedItem.IsPostCompleted)
                            {
                                var msg = "只有在Item状态为Error或IsPostCompleted=true时GetNextMessage才允许返回null,否则请在GetNextMessage中递归调用";
                                try
                                {
                                    throw new Exception(msg);
                                }
                                catch (Exception ex)
                                {
                                    //这个奇怪的自己throw 自己catch,是为了在调试模式下,停在上面位置,点击继续后又不会导致程序停止工作。
                                }
                            }
#endif
                            Env.Instance.Logger.Log(LogLevel.Warn, "A null message was created by" + selectedItem);
                            lock (locker) sendableList.Remove(selectedItem);
                        }
                    }
                }
                //传送文件的过程中,如果点击Browse响应会很慢,这样能解决吗?
                //Thread.Sleep(2);
            }//end while
            IsWorking = false;
        }