RaspberryPi上的Mono:System.InvalidOperationException:事件已设置

时间:2016-05-04 18:51:28

标签: c# multithreading mono raspberry-pi

我使用RaspberryPi和Mono来运行应用程序。它从stdin读取输入并将输出打印到stdout。 stdin中的每一行都是记录,stdout中的每一行都是记录。输入记录可能会被删除。

我使用两个线程:首先我使用了生产者/消费者模式。制作人只需将stdin行放入队列即可。消费者总是检查队列并处理这些项目。

我使用Monitor-class来实现它,以及信号量和AutoResetEvent。一段时间后我总是遇到这个错误:

Unhandled Exception:
System.InvalidOperationException: The event is already set
  at System.Threading.CountdownEvent.Signal (Int32 signalCount) [0x00000] in <filename unknown>:0
  at System.Threading.CountdownEvent.Signal () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.CountdownContinuation.Execute () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.ProcessCompleteDelegates () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.Finish () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.ThreadStart () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.Execute () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.TpScheduler.<QueueTask>m__0 (System.Object l) [0x00000] in <filename unknown>:0
  at System.Threading.Thread.StartInternal () [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: The event is already set
  at System.Threading.CountdownEvent.Signal (Int32 signalCount) [0x00000] in <filename unknown>:0
  at System.Threading.CountdownEvent.Signal () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.CountdownContinuation.Execute () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.ProcessCompleteDelegates () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.Finish () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.ThreadStart () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.Task.Execute () [0x00000] in <filename unknown>:0
  at System.Threading.Tasks.TpScheduler.<QueueTask>m__0 (System.Object l) [0x00000] in <filename unknown>:0
  at System.Threading.Thread.StartInternal () [0x00000] in <filename unknown>:0

目前我使用&#34;愚蠢的&#34;做法。 我从这里使用阅读器:How to add a Timeout to Console.ReadLine()?

我使用无限循环,它始终从stdin获取可用行并将最后一行传递给工作者。工人需要很多时间来完成工作,然后一切都重新启动。

代码:

using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Collections.Generic;
using System.Threading;
using SourceAFIS.Simple;
using NetJSON;

namespace fingerprint_to_iso
{
    class Program
    {
        private static AfisEngine afis;
        private static Queue<Tuple<DateTime, string>> inputFiles;
        private static volatile bool stop;
        private static AutoResetEvent queueEvent;

        private static void printJson(Tuple<DateTime, string> fingerprintImage)
        {
            ... /* This takes about ~2s */
            Console.WriteLine(json);
        }

        /* https://stackoverflow.com/questions/57615/how-to-add-a-timeout-to-console-readline */
        class Reader
        {
            private static Thread inputThread;
            private static AutoResetEvent getInput, gotInput;
            private static string input;

            static Reader()
            {
                getInput = new AutoResetEvent(false);
                gotInput = new AutoResetEvent(false);
                inputThread = new Thread(reader);
                inputThread.IsBackground = true;
                inputThread.Start();
            }

            private static void reader()
            {
                while (true)
                {
                    getInput.WaitOne();
                    input = Console.ReadLine();
                    gotInput.Set();
                }
            }

            public static string ReadLine(int timeOutMillisecs, ref bool eof)
            {
                getInput.Set();
                bool success = gotInput.WaitOne(timeOutMillisecs);
                if (success)
                {
                    if (input == null)
                    {
                        eof = true;
                    }
                    return input;
                }
                else
                {
                    eof = false;
                    return null;
                }
            }
        }

        static void Main(string[] args)
        {
            afis = new AfisEngine();
            Reader reader = new Reader();

            while (true)
            {
                string line = null;
                string tmp = null;
                bool eof = false;
                int timeout = 100;
                while ((tmp = Reader.ReadLine(timeout, ref eof)) != null && !eof)
                {
                    if (line != null && File.Exists(line))
                    {
                        File.Delete(line);
                        Console.WriteLine(line + " dropped");
                    }
                    line = tmp;
                    timeout = 5; // Decrease timeout
                }
                if (line != null)
                {
                    printJson(new Tuple<DateTime, string>(DateTime.Now, line));
                }
                if (eof)
                {
                    break;
                }
            }
        }
    }
}

因此,使用线程的唯一地方是Reader类。我不明白为什么我总是得到这个线程错误?有时我会在几秒钟之后得到它,有时几分钟之后。

也许有人有想法?

非常感谢

-edit -

今天我继续测试。不幸的是我到目前为止没有得到错误。我仍然创建了一个更小的代码版本,我很有兴趣修复这个bug。我让它现在运行,直到我收到错误。当出现错误时,我将发布最小代码以及有关单声道版本的更多详细信息。

-edit -

测试现在运行了几个小时,但没有任何反应。 SourceAFIS(https://sourceafis.angeloflogic.com/)似乎确实存在问题。谢谢你的帮助:)

0 个答案:

没有答案