internal override void InternalWormHole(object obj) { //文件开始发送时,会调用这个函数。所以ProcessingItems里面存储的,是所有尝试开始过的Item,如果成功了,就会从里面移除,不管是主动发送完毕,还是对方已经有这个文件,直接变成完成状态。 //TODO 现在有个问题没有解决,获取正在等待确认的文件,或者出错的文件,是应该在这个ProcessingItems里面呢,还是应该去Items属性里面?因为这两个是重复的。 //作为临时的解决方案,可以查找ProcessingItems里面的Item的相对路径是不是"", 如果是,就不要显示,因为Items那里已经显示了。 //TODO 重构 有没有更好的解决方案?不要冒然删除ProcessingItems,因为Items属性只管理了顶层的文件、文件夹。嵌套的子文件在那里面查找不到。 if (obj is FileItem) { //这里的item可以是嵌套很深的文件。在构造requester的时候设置item的回调达不到这个效果,除非遍历子元素。 //文件等待确认或者出错,会转移到PendingItems里面去。会话会尽量完成能传输完毕的文件,传不成功的(出错或没有得到及时确认)会留在这里。 var fi = obj as FileItem; if (ProcessingItems.Find(i => { return(i.ID == fi.ID); }) != null || fi.TransferState == TransferState.Confirmed) { return; //如果滥用了InternalWormHole,这样可以避免一下,否则会导致事件被触发多次。 } ProcessingItems.Add(fi); fi.Confirmed += (o) => ProcessingItems.Remove(fi); fi.Completed += (o) => { if (fi.NeedConfirm) { fi.TransferState = TransferState.WaitingConfirm; } }; } }
//速度可以计算出来?用传送开始时间、传输的数据量,再用一个timer定时更新速度就可以了。更新总的速度,或者一个会话的速度都可以。 //public event Action<int> SpeedChanged; internal protected override void OnInitRequest() { SendItemsMessage message = new SendItemsMessage(Items); Items.ForEach(item => { if (item is FileItem) { ProcessingItems.Add(item); } }); PostMessage(message); }