Example #1
0
        public void DoubleStopTest()
        {
            //arrange
            var producer = new ProducerConsumer <Block>();
            var block    = new Block(0, null);

            //act
            producer.Stop();
            producer.Stop();

            //assert
            Assert.ThrowsException <InvalidOperationException>(() => producer.Enqueue(block));
        }
Example #2
0
        public void DequeueTest_DequeueItemFromStoppedQueueIsNull()
        {
            //arrange
            var producer = new ProducerConsumer <Block>();

            //act
            producer.Stop();
            var resultItemFromDequeue = producer.Dequeue();

            //assert
            Assert.IsNull(resultItemFromDequeue);
        }
Example #3
0
 public int Run()
 {
     try
     {
         workingThreads.ForEach(thread => thread.Start());
         while (!interrupted)
         {
             if (tasks.Size() > 2 * concurrency || results.Size() > 2 * concurrency)
             {
                 Thread.Yield();
                 continue;
             }
             var data = getDataBlock();
             if (data == null)
             {
                 tasks.Stop();
                 break;
             }
             tasks.Enqueue(data);
         }
         // join only processing tread and not the result aggregator
         for (var i = 1; i < workingThreads.Count; i++)
         {
             workingThreads[i].Join();
         }
         // notifies the result aggregator thread that no new information would be added and wait for it to finish
         results.Stop();
         workingThreads[0].Join();
     } catch (HandledException e)
     {
         this.Interrupt();
     } catch (Exception e)
     {
         Console.WriteLine($"Unhandled exception: {e.Message}");
         this.Interrupt();
     }
     return(interrupted ? 1 : 0);
 }
        // This is a HUGE test which involves actual threads and takes time,
        // so technically it is not a unit test.
        // But this is a sort of pet-form of the whole project, and covers the main sense of it.
        // Actually, this is a code of my prototype application so it is also not well structured.
        //
        // Whats going on:
        // - "Reader" thread produces a sequence of numbers and passes to Producer-Consumer (P-C)
        // - A number of worker threads consume and "process" them (actually do nothing with a random delay)
        //      then pass to the next P-C
        // - A "writer" thread collects all the integers passed in the list.
        // The goal of the test is to ensure that the final list contains exactly the same numbers
        // as produced by "reader"
        public void ProducerConsumerShouldWork()
        {
            var readerPc      = new ProducerConsumer <IntTask>(8, new ProducerConsumerQueue <IntTask>());
            var processorsPcs = new List <ProducerConsumer <IntTask> >();
            var finishPc      = new ProducerConsumer <IntTask>(8, new ProducerConsumerQueue <IntTask>());

            const int integersToReadCount = 50;
            var       integersToRead      = new List <int>(integersToReadCount);
            var       rand = new Random(DateTime.Now.Millisecond);

            for (var i = 0; i < integersToReadCount; i++)
            {
                integersToRead.Add(rand.Next(10000));
            }
            var readerThread = new Thread(new ThreadStart(() =>
            {
                var rnd    = new Random(DateTime.Now.Millisecond);
                var currId = 0;
                for (int i = 0; i < integersToReadCount; i++)
                {
                    var pc = new IntTask {
                        Id = i, Data = integersToRead[i]
                    };
                    readerPc.Push(pc);
                    Thread.Sleep(rnd.Next(10));
                    currId++;
                }
                readerPc.Stop();

                var endPc = new IntTask {
                    Id = currId, Data = 0
                };
                finishPc.Push(endPc);
            }));

            readerThread.Start();

            for (int i = 0; i < 4; i++)
            {
                var processorId = i;
                var prodCons    = new ProducerConsumer <IntTask>(4, new ProducerConsumerOrderedQueue <IntTask>());
                processorsPcs.Add(prodCons);
                var processorThread = new Thread(new ThreadStart(() =>
                {
                    var rnd = new Random(DateTime.Now.Millisecond);
                    var pc  = readerPc.Pop();
                    while (pc != null)
                    {
                        processorsPcs[processorId].Push(pc);
                        pc = readerPc.Pop();
                        Thread.Sleep(rnd.Next(1000));
                    }
                }));
                processorThread.Start();
            }

            var writerList = new List <int>(integersToReadCount);
            var writer     = new Thread(new ThreadStart(() => {
                int currId = 0;

                while (true)
                {
                    var allProcessorsEmpty = true;
                    for (int i = 0; i < processorsPcs.Count; i++)
                    {
                        var t = processorsPcs[i].Peek();
                        if (t != null)
                        {
                            allProcessorsEmpty = false;
                            if (t.Id == currId)
                            {
                                t = processorsPcs[i].Pop();
                                writerList.Add(t.Data);
                                currId++;
                            }
                        }
                    }
                    if (allProcessorsEmpty)
                    {
                        var finishPcData = finishPc.Peek();
                        if (finishPcData != null && finishPcData.Id == currId)
                        {
                            break;
                        }
                    }
                }
            }));

            writer.Start();
            writer.Join();

            Assert.IsTrue(integersToRead.SequenceEqual(writerList));
        }
Example #5
0
File: Form1.cs Project: vinhch/DDD
        private void btn_Satrt_Click(object sender, EventArgs e)
        {
            if (!_noticeFlag)
            {
                _noticeFlag     = true;
                _noticeDateTime = DateTime.Now;
                Logging("启动[提醒]服务");
                SetbtnState(btn_Satrt, "停止[提醒]服务", true);
                SetlblState(lbl_State, "[提醒]扫描服务运行中(" + _noticeDateTime + ")", Color.Green);

                //重置提醒扫描状态:正在扫描--> 等到扫描
                var resetStandbyTask = new Task <bool>(() =>
                {
                    var isReset = false;
                    try
                    {
                        isReset = ResetAllRemindScan();
                    }
                    catch
                    {
                    }
                    return(isReset);
                });
                resetStandbyTask.Start();
                resetStandbyTask.Wait();
                var isSuccess = resetStandbyTask.Result;
                if (isSuccess)
                {
                    Logging("重置\"扫描中\"的[提醒]扫描服务为等待扫描成功!");
                }
                else
                {
                    Logging("[提醒]扫描服务启动失败:重置\"扫描中\"的[提醒]扫描服务为等待扫描失败!");

                    _noticeFlag = false;
                    SetbtnState(btn_Satrt, "启动[提醒]扫描服务", true);
                    SetlblState(lbl_State, "[提醒]扫描服务停止", Color.Red);
                    return;
                }

                //初始化相关变量、工作线程
                //等到重置“发送中”任务结束后,才能执行下面任务:
                //获取[未提醒]列表数据,为[发起提醒]生产者提供生产方法
                var getRetryTimes = 0;
                Func <List <string> > ProduceFunc = () =>
                {
                    //休眠获取[提醒]列表数据,主要为了间断查询。
                    Thread.Sleep(_SleepQuery);
                    var unList = new List <string>();
                    try
                    {
                        unList = GetTaskList();
                        if (unList.Count > 0)
                        {
                            Logging("获取[提醒]队列成功!");
                        }
                        getRetryTimes = 0;
                    }
                    catch (Exception ex)
                    {
                        getRetryTimes = getRetryTimes + 1;
                        if (getRetryTimes >= _GetQueryRetryTimes)
                        {
                            _noticeFlag = false;
                            Logging(
                                "[提醒]服务意外停止:获取[未提醒]队列连续失败" + getRetryTimes + "次!|| 错误原因:" +
                                (ex.InnerException == null ? ex.Message : ex.InnerException.ToString()),
                                (string.IsNullOrWhiteSpace(ex.StackTrace) ? "" : ex.StackTrace));
                            ChangeAllServerState();
                            if (_producerConsumer != null)
                            {
                                _producerConsumer.Stop();
                            }
                        }
                        else
                        {
                            Logging(
                                "获取[未提醒]队列连续失败" + getRetryTimes + "次!|| 错误原因:" +
                                (ex.InnerException == null ? ex.Message : ex.InnerException.ToString()),
                                (string.IsNullOrWhiteSpace(ex.StackTrace) ? "" : ex.StackTrace));
                        }
                    }
                    return(unList);
                };

                int consumeRetryTimes = 0;
                //为[未提醒]消费者提供消费方法
                Action <string> notNoticeAction = item =>
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        long durTime     = -1;
                        var  durTimeUnit = "毫秒";
                        var  durTimer    = new Stopwatch();
                        durTimer.Start();
                        try
                        {
                            //执行活动提交服务
                            var result = PostRemind(item);
                            durTimer.Stop();
                            durTime = durTimer.ElapsedMilliseconds;
                            if (durTime >= 1000)
                            {
                                durTimeUnit = "秒";
                                durTime     = durTime / 1000;
                            }
                            lock (_noticeLock)
                            {
                                consumeRetryTimes = 0;
                            }
                            Logging("[未提醒]提交成功." + "(商家ID:" + item + ",运行结果:" + (result ? "提醒成功" : "提醒失败") + ",耗时:" +
                                    durTime.ToString() + durTimeUnit + ")");
                        }
                        catch (Exception ex)
                        {
                            lock (_noticeLock)
                            {
                                consumeRetryTimes++;
                                if (consumeRetryTimes >= _GetQueryRetryTimes)
                                {
                                    _noticeFlag = false;
                                    Logging(
                                        "[未提醒]服务意外停止:提交提醒服务连续失败" + consumeRetryTimes + "次![其中包含ID:" + item +
                                        "]  || 错误原因:" +
                                        (ex.InnerException == null ? ex.Message : ex.InnerException.ToString()),
                                        (string.IsNullOrWhiteSpace(ex.StackTrace) ? "" : ex.StackTrace));
                                    ChangeAllServerState();
                                    if (_producerConsumer != null)
                                    {
                                        _producerConsumer.Stop();
                                    }
                                }
                                else
                                {
                                    Logging(
                                        "[未提醒]提交提醒服务连续失败" + consumeRetryTimes + "次![其中包含商家ID:" + item +
                                        "] || 错误原因:" +
                                        (ex.InnerException == null ? ex.Message : ex.InnerException.ToString()),
                                        (string.IsNullOrWhiteSpace(ex.StackTrace) ? "" : ex.StackTrace));
                                }
                            }
                        }
                        Thread.Sleep(_SleepPost);
                    }
                };
                //构造生产消费模式,初始化如生产方法,消费方法,指定消费者数量
                _producerConsumer = new ProducerConsumer <string>(ProduceFunc,
                                                                  notNoticeAction, _remainStandbyCount,
                                                                  _reminTaskNum);
                _producerConsumer.Start();
            }
            else //停止
            {
                _noticeFlag = false;
                if (_producerConsumer != null)
                {
                    _producerConsumer.Stop();
                }
                Logging("手动停止[未提醒]扫描服务");

                SetbtnState(btn_Satrt, "启动[提醒]扫描服务", true);
                SetlblState(lbl_State, "[提醒]扫描服务停止", Color.Red);
            }
        }