Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#我想线程安全有问题吧?_C#_Multithreading - Fatal编程技术网

C#我想线程安全有问题吧?

C#我想线程安全有问题吧?,c#,multithreading,C#,Multithreading,大家好,我有几个问题要问为什么会发生这些事情。首先,我有一个初始启动,不管您将numOfAsynchEx设置为多少个进程。这应该用ExecuteThread类的两个不同实例启动两个不同的线程,并且有两个相同的方法(ThreadProcess),但变量不同,对吗 int numOfAsynchEx = 2; for (int i = 0; i < numOfAsynchEx; i++) { if (entryQueue.Count &g

大家好,我有几个问题要问为什么会发生这些事情。首先,我有一个初始启动,不管您将numOfAsynchEx设置为多少个进程。这应该用ExecuteThread类的两个不同实例启动两个不同的线程,并且有两个相同的方法(ThreadProcess),但变量不同,对吗

int numOfAsynchEx = 2;
        for (int i = 0; i < numOfAsynchEx; i++)
        {
            if (entryQueue.Count > 0)
            {
                ExecuteThread eT = new ExecuteThread(entryQueue.Dequeue()
                    new startNextThread(startNextThread));

                Thread newThread = new Thread(eT.ThreadProcess);
                newThread.Start();
                metrics.TotalAttempted++;
                metrics.ThreadsRunning++;
            }
        }
编辑这里是执行线程类 公共类ExecuteThread {

出于某种原因,这不是同时启动两个线程并异步执行它们。而是一次执行一个线程。我不明白为什么。有人能告诉我吗


编辑:在玩了一段时间后,当我注释掉redirectStandardOutput和useShellExecute时,该程序与以前一样工作正常。我现在的问题是如何重定向输出,因为我显然不能这样做?

只是一些建议

  • 什么是entryQueue?普通队列{T}不是线程安全的
  • 自从entryQueue.Count和 entryQueue.Dequeue()不是原子地一起完成的
  • 您可能想使用Interlocked.Increment和decreation代替 普通的++和--

您的代码实际上不会按原样编译-请给我们一个简短但完整的示例来说明问题。您是如何观察到它们不是异步的?您正在变异共享变量,显然没有同步。这充满了危险。请尝试在异步方法内放置断点,如果它们运行异步,则断点point应该命中两次。我试图给出尽可能多的结果,但我无法提供一个用于特定目的的完全有效的示例。但这应该是您解决线程问题所需的全部。这是一个普通队列。我想我将使用线程安全队列,但这能解决我所有的问题吗?我不知道队列是如何出现问题的,因为它是su假设只启动2个线程,然后每个线程回调方法启动另一个线程。@Joey我不确定这是否能解决“所有问题”但要想有机会真正获得生产质量代码,您必须首先解决这些问题。我从自己的错误中认识到,多线程是很棘手的,应该非常小心和尊重地处理……entryQueue是一个队列。如何使其同步?CatalogEntries是在e伦敦证交所。
private void startNextThread(ParsingInfo info)
    {
        metrics.ThreadsRunning--;
        if (entryQueue.Count > 0)
        {
            metrics.TotalAttempted++;
            ExecuteThread eT = new ExecuteThread(entryQueue.Dequeue()
                new startNextThread(startNextThread));

            Thread newThread = new Thread(eT.ThreadProcess);
            newThread.Start();
            metrics.ThreadsRunning++;
        } 
        else if(metrics.ThreadsRunning == 0)
        {
            ThreadsDone = true;
        }
    }
    private CatalogEntry entry;
    private startNextThread callBackDelegate;
    private ProcessStartInfo startInfo;
    private ParsingInfo parseInfo;

    public ExecuteThread(CatalogEntry entry, startNextThread callBack)
    {
        parseInfo = new ParsingInfo();
        this.entry = entry;
        callBackDelegate = callBack;

        createStartInfo();
        InstantiateProcess();
    }



    private void createStartInfo()
    {
        startInfo = new ProcessStartInfo(exePath);
        startInfo.CreateNoWindow = true;
        startInfo.RedirectStandardOutput = true;
        startInfo.UseShellExecute = false;
        //startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.Arguments = + filePath + " " ;
    }

    private void InstantiateProcess()
    {
        fileParserExe = new Process();
        fileParserExe.StartInfo = startInfo;
        fileParserExe.EnableRaisingEvents = true;
    }
    private void Parse()
    {
        try
        {
            this.fileParserExe.Start();
            this.fileParserExe.WaitForExit();
            parseInfo.additionalMessage += fileParserExe.StandardOutput.ReadToEnd();
        }
        catch (Exception e)
        {
            parseInfo.additionalMessage += e.ToString();
            parseInfo.additionalMessage += "Could not locate single file parser executable: " + exePath;
        }

    }

    public void ThreadProcess()
    {
        this.parseInfo.fileName = entry.fileName;
        this.parseInfo.startTime = DateTime.Now;
        Parse();
        this.parseInfo.endTime = DateTime.Now;
        this.parseInfo.SetElapsedTime();

        if (this.callBackDelegate != null)
        {
            this.callBackDelegate(this.parseInfo);
        }
    }
}