예제 #1
0
        /// <summary>
        /// 添加任务(有返回值)
        /// </summary>
        /// <param name="item">传入任务参数</param>
        /// <param name="func">需要执行的任务,返回值为任务完成后需要接受的值</param>
        /// <param name="taskFinishAction">任务结束后需要返回的结果,如果执行成功,其中T2的值为func委托的响应值</param>
        public void Add(T item, Func <T, CancellationTokenSource, T2> func,
                        Action <bool, T2, Exception> taskFinishAction = null)
        {
            Guid guid = Guid.NewGuid();

            AwaitList.Add(guid, new TaskJobParam <T>(guid, item));
            StartProcessForWait(func, taskFinishAction);
        }
예제 #2
0
        /// <summary>
        /// Applies the specified value.
        /// </summary>
        /// <param name="value">The value.</param>
        private void applyString(byte[] value)
        {
            if (operations.Count == 0)
            {
                receivedData.Enqueue(value);
                return;
            }

            object nextOp = operations.Peek();

            if (nextOp is AwaitString && !((AwaitString)nextOp).readSize)
            {
                AwaitString op   = (AwaitString)nextOp;
                int         size = Convert.ToInt32(Encoding.ASCII.GetString(value));
                op.readSize = true;
                op.size     = size;
                op.data     = new byte[] {};
                if (op.size < 0)
                {
                    operations.Pop();
                    applyString(null);
                }
            }
            else if (nextOp is AwaitList && !((AwaitList)nextOp).readLength)
            {
                AwaitList op     = (AwaitList)nextOp;
                int       length = Convert.ToInt32(Encoding.ASCII.GetString(value));
                op.readLength = true;
                op.length     = length;
                if (op.length < 0)
                {
                    operations.Pop();
                    applyString(null);
                }
                op.data = new object[length];
            }
            else
            {
                if (!applyToList(value))
                {
                    receivedData.Enqueue(value);
                    operations.Push(new AwaitCrLf());
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Applies to list.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns><c>true</c> if the object was applied to a list, <c>false</c> if another application should be attempted.</returns>
        private bool applyToList(object value)
        {
            object nextOp = operations.Peek();

            if (!(nextOp is AwaitList))
            {
                return(false);
            }
            AwaitList op = (AwaitList)nextOp;

            if (op.objectsRead >= op.length)
            {
                return(false);
            }
            else
            {
                op.data[op.objectsRead++] = value;
                return(true);
            }
        }
예제 #4
0
        /// <summary>
        /// 开始执行等待进行的任务
        /// </summary>
        private void StartProcessForWait(Func <T, CancellationTokenSource, T2> func,
                                         Action <bool, T2, Exception> taskFinishAction)
        {
            if (AwaitList.Count > 0 && IsStartNewProcess)
            {
                TaskJobParam <T> taskJobParam = base.GetFirstJob <TaskJobParam <T> >(AwaitList);
                if (taskJobParam != null)
                {
                    if (AwaitList.ContainsKey(taskJobParam.Id))
                    {
                        AwaitList.Remove(taskJobParam.Id);
                    }

                    StartNewProcess(taskJobParam, func, taskFinishAction);
                }
            }
            else
            {
                if (_duration > 0)
                {
                    Thread.Sleep(_duration);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Updates the internal states based on the latest bytes read.
        /// </summary>
        /// <param name="bytesRead">The number of bytes read.</param>
        /// <exception cref="System.NotImplementedException">
        /// Operation not implemented for  + encoding.GetString(buffer, bufferIndex, 1)
        /// or
        /// Don't know what to do.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Protocol Violation. Expected CR-LF.
        /// or
        /// Protocol Violation. Expected CR.
        /// or
        /// Protocol Violation. Expected LF.
        /// </exception>
        public void update(int bytesRead)
        {
            int bufferIndex = 0;

            while (bufferIndex < buffer.Length && bufferIndex < bytesRead)
            {
                if (operations.Count == 0)
                {
                    operations.Push(new AwaitCommand());
                }
                object nextOp = operations.Peek();
                if (nextOp is AwaitCommand)
                {
                    switch (buffer[bufferIndex])
                    {
                    case PLUS:
                        operations.Pop();
                        operations.Push(new AwaitSimpleString());
                        ++bufferIndex;
                        continue;

                    case DOLLAR:
                        operations.Pop();
                        operations.Push(new AwaitString {
                            readSize = false
                        });
                        operations.Push(new AwaitSimpleString());
                        ++bufferIndex;
                        continue;

                    case COLON:
                        operations.Pop();
                        operations.Push(new AwaitInt());
                        ++bufferIndex;
                        continue;

                    case ASTERISK:
                        operations.Pop();
                        operations.Push(new AwaitList {
                            readLength = false
                        });
                        operations.Push(new AwaitSimpleString());
                        ++bufferIndex;
                        continue;

                    case MINUS:
                        operations.Pop();
                        operations.Push(new AwaitError());
                        operations.Push(new AwaitSimpleString());
                        ++bufferIndex;
                        continue;

                    default:
                        throw new NotImplementedException("Operation not implemented for " + encoding.GetString(buffer, bufferIndex, 1));
                    }
                }
                else if (nextOp is AwaitCrLf)
                {
                    AwaitCrLf op = (AwaitCrLf)nextOp;
                    int       availableLength = buffer.Length - bufferIndex;
                    if (availableLength < 1)
                    {
                        continue;
                    }
                    if (!op.cr)
                    {
                        if (availableLength >= 2)
                        {
                            if (buffer[bufferIndex] == CR && buffer[bufferIndex + 1] == LF)
                            {
                                operations.Pop();
                                bufferIndex += 2;
                            }
                            else
                            {
                                throw new InvalidOperationException("Protocol Violation. Expected CR-LF.");
                            }
                        }
                        else
                        {
                            if (buffer[bufferIndex] == CR)
                            {
                                op.cr = true;
                                ++bufferIndex;
                            }
                            else
                            {
                                throw new InvalidOperationException("Protocol Violation. Expected CR.");
                            }
                        }
                    }
                    else
                    {
                        if (buffer[bufferIndex] == LF)
                        {
                            operations.Pop();
                            ++bufferIndex;
                        }
                        else
                        {
                            throw new InvalidOperationException("Protocol Violation. Expected LF.");
                        }
                    }
                }
                else if (nextOp is AwaitSimpleString)
                {
                    AwaitSimpleString  op            = (AwaitSimpleString)nextOp;
                    IEnumerable <byte> partialBuffer = buffer.Skip(bufferIndex).Take(bytesRead - bufferIndex);
                    byte[]             potential     = op.data == null?partialBuffer.ToArray() : op.data.Concat(partialBuffer).ToArray();

                    int indexCrLf = potential.indexOf(CrLf);
                    if (indexCrLf == -1)
                    {
                        op.data     = potential;
                        bufferIndex = buffer.Length;
                    }
                    else
                    {
                        byte[] stringData = potential.Take(indexCrLf).ToArray();
                        operations.Pop();
                        if (operations.Count > 0 && operations.Peek() is AwaitError)
                        {
                            operations.Pop();
                            apply(new RedisErrorException(encoding.GetString(stringData)));
                        }
                        else
                        {
                            applyString(stringData);
                        }
                        bufferIndex += indexCrLf + CrLf.Length - (op.data == null ? 0 : op.data.Length);
                    }
                }
                else if (nextOp is AwaitInt)
                {
                    AwaitInt           op            = (AwaitInt)nextOp;
                    IEnumerable <byte> partialBuffer = buffer.Skip(bufferIndex).Take(bytesRead - bufferIndex);
                    byte[]             potential     = op.data == null?partialBuffer.ToArray() : op.data.Concat(partialBuffer).ToArray();

                    int indexCrLf = potential.indexOf(CrLf);
                    if (indexCrLf == -1)
                    {
                        op.data     = potential;
                        bufferIndex = buffer.Length;
                    }
                    else
                    {
                        byte[] stringData   = potential.Take(indexCrLf).ToArray();
                        string valueLiteral = _encoding.GetString(stringData);
                        operations.Pop();
                        long value;
                        if (long.TryParse(valueLiteral, out value))
                        {
                            apply(value);
                        }
                        else
                        {
                            apply(new Exception(string.Format("Failed to parse {0} as an integer", valueLiteral)));
                        }
                        bufferIndex += indexCrLf + CrLf.Length - (op.data == null ? 0 : op.data.Length);
                    }
                }
                else if (nextOp is AwaitString)
                {
                    AwaitString op              = (AwaitString)nextOp;
                    int         currentSize     = op.data.Length;
                    int         availableLength = buffer.Length - bufferIndex;
                    if (currentSize + availableLength >= op.size)
                    {
                        int    count      = op.size - op.data.Length;
                        byte[] stringData = op.data.Concat(buffer.Skip(bufferIndex).Take(count)).ToArray();
                        operations.Pop();
                        applyString(stringData);
                        bufferIndex = bufferIndex + count;
                        operations.Push(new AwaitCrLf());
                        continue;
                    }
                    else
                    {
                        op.data     = op.data.Concat(buffer.Skip(bufferIndex).Take(availableLength)).ToArray();
                        bufferIndex = bufferIndex + availableLength;
                    }
                }
                else if (nextOp is AwaitList)
                {
                    AwaitList op = (AwaitList)nextOp;
                    if (op.objectsRead < op.length)
                    {
                        operations.Push(new AwaitCommand());
                    }
                }
                else
                {
                    throw new NotImplementedException("Don't know what to do.");
                }


                nextOp = operations.Count > 0 ? operations.Peek() : null;
                while (nextOp is AwaitList && ((AwaitList)nextOp).objectsRead >= ((AwaitList)nextOp).length)
                {
                    operations.Pop();
                    apply(((AwaitList)nextOp).data);
                    nextOp = operations.Count > 0 ? operations.Peek() : null;
                }

                if (operations.Count == 0)
                {
                    // Opportunity here to convert from "internal" state to "external" state.
                    Queue receivedObject = new Queue(receivedData.Count);
                    while (receivedData.Count > 0)
                    {
                        receivedObject.Enqueue(receivedData.Dequeue());
                    }
                    _onObjectReceived(new ObjectReceivedEventArgs(receivedObject));
                }
            }
        }