private void SendWorker_DoWork(object sender, DoWorkEventArgs e) { var work = sender as BackgroundWorker; if (work == null) { return; } try { while (!work.CancellationPending) { if (messageList.Count == 0 && sendableList.Count == 0) { notEmptyWaiter.WaitOne(); } Message message = null; if (messageList.Count > 0) { lock (locker) message = messageList.Dequeue(); SendMessageByChannel(message); } else if (sendableList.Count > 0) { ISendable selectedItem = null; if (sendableList.Count > 0) { lock (locker) { //计算优先级,除了根据splittable的Priority之外,还要根据上次的处理时间, //这样的话,才能做到如果有几个任务同时进行(发文件,收文件,浏览,同步)的时候,每个任务都能得到响应。 //但一个splittable内部不考虑上次处理时间。因为同一批次的文件,并行发送没有意义 sendableList.Sort(SendableComparer <ISendable> .Instance); selectedItem = sendableList[0]; } if (selectedItem is SequencableItem) { var seq = selectedItem as SequencableItem; //上来就尝试读取消息。如果是空文件,返回null。 message = seq.GetNextMessage(); if (!seq.HasNext || message == null) { //如果没有内容了,或者读取过程中出错了,都不再尝试继续发消息。 lock (locker) sendableList.Remove(message); } if (!seq.HasNext && message != null) { message.TransferCompleted.Observers += (msg) => seq.TransferCompleted.Emit(seq); seq.PostCompleted.Emit(seq); } } else { //不管出不出错,都移除了。 message = selectedItem.ToMessage(); lock (locker) sendableList.Remove(message); } } //ToMessage或者GetNextMessage可能发生异常。例如文件读取错误 if (message != null) { SendMessageByChannel(message); } } } } finally { //notEmptyWaiter.Close(); } }