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; }