AsyncStreamCopier类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议。因为不能公开3.x版本的源码,所以基于此版本进行学习。3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大。
/*请注意使用以下代码,需遵循GplV3协议*/

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;

namespace DPSBase
{

    public class AsyncStreamCopier
    {
        /// <summary>
        /// 拷贝数据完成 触发的事件
        /// </summary>
        public event EventHandler Completed;

        private byte[] buffer = new byte[4096];

        public AsyncStreamCopier()
        {
        }

        /// <summary>
        ///开始一个异步的数据拷贝
        /// </summary>

        public void Start(Stream input, Stream output)
        {
            GetNextChunk(new Stream[] { input, output });
        }

        private void GetNextChunk(Stream[] streams)
        {
            var input = streams[0];
            //把Stream[0] 中的输入数据流中的数据读取到buffer中,当buffer中的数据读取完成后,触发InputReadComplete方法
            input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, streams);
        }

        private void InputReadComplete(IAsyncResult ar)
        {
            var streams = ar.AsyncState as Stream[];
            var input = streams[0];
            var output = streams[1];

            //等待挂起的异步读取完成。
            int bytesRead = input.EndRead(ar);

            if (bytesRead == 0)
            {
                RaiseCompleted();
                return;
            }

            //  同步写入
            output.Write(buffer, 0, bytesRead);

            //  读取下一数据块
            GetNextChunk(streams);
        }

        private void RaiseCompleted()
        {
            if (Completed != null)
            {
                Completed(this, EventArgs.Empty);
            }
        }

        public static void CopyStreamTo(Stream source, Stream destination)
        {
            //信号灯-默认无信号  来进程不得通行
            var completedEvent = new ManualResetEvent(false);

            // copy as usual but listen for completion
            var copier = new AsyncStreamCopier();

            //一旦完成,给信号
            copier.Completed += (s, e) => completedEvent.Set();

            //开始拷贝数据,如果拷贝数据完成,触发信号灯
            copier.Start(source, destination);

            //有交警 需要信号 否则等待
            completedEvent.WaitOne();
        }
    }
}
 http://www.cnblogs.com/networkcomms
http://www.networkcoms.cn 编辑
时间: 2024-10-13 06:01:20

AsyncStreamCopier类(NetworkComms 2.3.1源码了解和学习)的相关文章

ConnectionInfo类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ /// <summary> /// 连接状态枚举类 /// </summary> public enum ConnectionState { /// <summary> /// 未定义 是连接的初始状态. /// </summ

PacketHeaderStringItems枚举类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ ///<summary> /// 字符类型的选项 PacketHeader类中会用到此枚举类型 /// </summary> public enum PacketHeaderStringItems { /// <summary> /

PacketHeaderLongItems枚举类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ /// <summary> /// Long类型的选项 PacketHeader类中会用到此枚举类型 /// </summary> public enum PacketHeaderLongItems { /// <summary>

PacketHeader类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ /// <summary> /// PacketHeader 包含发送,接收,重建数据包的相关信息 /// </summary> [ProtoContract] public sealed class PacketHeader { [Proto

ThreadSafeStream 类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Security.Cryptography; namespace

StreamSendWrapper 类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ using System; using System.Collections.Generic; using System.Text; using System.IO; namespace DPSBase { /// 发送全部或者部分数据流 public cl

ProtobufSerializer类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ using System; using System.Collections.Generic; using System.Text; using ProtoBuf; using System.IO; using System.Runtime.InteropS

DataSerializerProcessorAttribute类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /*请注意使用以下代码,需遵循GplV3协议*/ //在英文网站上购买 九折折扣代码: NCDN_PRCLW using System; using System.Collections.Generic; using System.Text; namespace DPSBase { /// <summary

SentPacket类(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议.因为不能公开3.x版本的源码,所以基于此版本进行学习.3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大. /// 一个包装类用来跟踪发送的数据包 如果检验和失败需要重新发送时可以使用 /// </summary> class SentPacket { public int SendCount { get; private set; } public Packet Packet { get; private s