예제 #1
0
            public static LockGuard Create(string key, string operationId, ExclusiveBlockConfiguration config)
            {
                var guard = new LockGuard(key, operationId, config);

                Task.Run(() => guard.StartAsync());
                return(guard);
            }
예제 #2
0
        public override async void Start(FrameBase frameBase)
        {
            var frame = frameBase as DataFrame;

            if (frame == null)
            {
                return;
            }

            try
            {
                var file = FileManager.Get(frame.Guid);
                if (file == null)
                {
                    throw new Exception("未能找到已打开的文件。");
                }

                FileStream    fs  = file.Item1;
                SemaphoreSlim lck = file.Item2;
                using (LockGuard lg = await LockGuard.WaitAsync(lck).ConfigureAwait(false))
                {
                    if (fs.Position != frame.DataOffset)
                    {
                        fs.Seek(frame.DataOffset, SeekOrigin.Begin);
                    }
                    await fs.WriteAsync(frame.Data, 0, frame.Data.Length).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                await SendError(frame, ex.Message).ConfigureAwait(false);
            }
        }
예제 #3
0
        public override async void Start(FrameBase frameBase)
        {
            var frame = frameBase as CloseFrame;

            if (frame == null)
            {
                return;
            }

            try
            {
                var file = FileManager.GetAndRemove(frame.Guid);
                if (file == null)
                {
                    throw new Exception("未能关闭文件:没有找到已打开的文件。");
                }

                FileStream    fs  = file.Item1;
                SemaphoreSlim lck = file.Item2;
                using (LockGuard lg = await LockGuard.WaitAsync(lck).ConfigureAwait(false))
                {
                    fs.Close();
                }

                await SendFrame(new CloseAnswerFrame(frame.Guid)).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await SendError(frame, ex.Message).ConfigureAwait(false);
            }
        }
예제 #4
0
 /// <summary>
 /// 向给定客户端发送帧。
 /// </summary>
 /// <exception cref="Exception"></exception>
 public virtual async Task Send(ClientDataBase client, FrameBase frame)
 {
     using (await LockGuard.WaitAsync(client.WriteLock).ConfigureAwait(false))
     {
         await WriteFrame(client.TcpClient.GetStream(), frame).ConfigureAwait(false);
     }
 }
예제 #5
0
 /// <summary>
 /// 线程安全地向服务端发送帧。
 /// </summary>
 /// <exception cref="Exception"></exception>
 public async Task SendAsync(FrameBase frame)
 {
     using (LockGuard lg = await LockGuard.WaitAsync(SemaphoreSend).ConfigureAwait(false))
     {
         if (Common.Configs.Debug)
         {
             Console.WriteLine("S >" + frame.GetType().ToString());
         }
         await WriteFrame(Tcp.GetStream(), frame).ConfigureAwait(false);
     }
 }
예제 #6
0
        public override async void Start(FrameBase frameBase)
        {
            var frame = frameBase as RequestFrame;

            if (frame == null)
            {
                return;
            }

            try
            {
                var file = FileManager.Get(frame.Guid);
                if (file == null)
                {
                    throw new Exception("未能找到已打开的文件。");
                }

                const int sizeMax = 1024 * 128 < Configs.MaxFrameSize ? 1024 * 128 : Configs.MaxFrameSize;
                const int sizeMin = 1024 < Configs.MaxFrameSize ? 1024 : Configs.MaxFrameSize;
                int       size    = sizeMin;

                byte[] buffer = new byte[sizeMax];
                long   offset = 0;
                using (LockGuard lg = await LockGuard.WaitAsync(file.Item2).ConfigureAwait(false))
                    using (FileStream fs = file.Item1)
                    {
                        SpeedRecorder recorder = new SpeedRecorder();
                        while (offset < fs.Length)
                        {
                            int count = await fs.ReadAsync(buffer, 0, size).ConfigureAwait(false);

                            DataFrame dataFrame = new DataFrame(frame.Guid)
                            {
                                FileSize   = fs.Length,
                                DataOffset = offset,
                                Data       = buffer.Take(count).ToArray(),
                            };

                            await SendFrame(dataFrame).ConfigureAwait(false);

                            offset += count;

                            recorder.Record(offset);
                            size = Math.Max(sizeMin, Math.Min(sizeMax, Common.Tools.SpeedRecorder.UpdateFrameSize((int)recorder.SpeedPerSecond, size)));
                        }
                    }
            }
            catch (Exception ex)
            {
                await SendError(frame, ex.Message).ConfigureAwait(false);
            }
        }
예제 #7
0
        /// <summary>
        /// Initializes an instance of the <see cref="ExclusiveLock"/>.
        /// </summary>
        /// <param name="key">The unique name of the exclusive lock.</param>
        /// <param name="operationId">Unique identifier of the caller thread, process or appdomain.</param>
        /// <param name="acquired">True if the lock is obtained otherwise false.</param>
        /// <param name="isFeatureAvailable">True if the feature is installed otherwise false.</param>
        /// <param name="config">The configuration of the exclusive execution.</param>
        public ExclusiveLock(string key, string operationId, bool acquired, bool isFeatureAvailable,
                             ExclusiveBlockConfiguration config)
        {
            Key                 = key;
            OperationId         = operationId;
            Acquired            = acquired;
            _config             = config;
            _isFeatureAvailable = isFeatureAvailable;
            if (Acquired && isFeatureAvailable)
            {
                _guard = LockGuard.Create(key, operationId, config);
            }

            Trace.WriteLine($"SnTrace: System: ExclusiveLock {key} #{operationId}. Created. Acquired = {acquired}. IsFeatureAvailable = {isFeatureAvailable}");
        }