Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.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,我有一个循环x次(10次)的编程,使用指定数量的线程(2次)。我正在使用线程数组: Thread[] myThreadArray = new Thread[2]; 我相信,我的循环计数器可以很好地启动前两个线程,但是当它到达循环3时,它会返回到线程0(基于零),它会挂起。奇怪的是,如果我在它们的线程中抛出一个MessageBox.Show(),以检查ThreadState(显示线程0仍在运行),它将继续执行10个循环中的9个。但是如果不存在MessageBox.Show(),则在启动第三个循环

我有一个循环x次(10次)的编程,使用指定数量的线程(2次)。我正在使用线程数组:

Thread[] myThreadArray = new Thread[2];
我相信,我的循环计数器可以很好地启动前两个线程,但是当它到达循环3时,它会返回到线程0(基于零),它会挂起。奇怪的是,如果我在它们的线程中抛出一个
MessageBox.Show()
,以检查
ThreadState
(显示线程0仍在运行),它将继续执行10个循环中的9个。但是如果不存在
MessageBox.Show()
,则在启动第三个循环时将挂起

我正在使用.NET3.5框架(我注意到.NET4.0使用了一种叫做continuations的东西…)

下面是一些代码示例:

        Thread[] threads = new Thread[2];
        int threadCounter = 0;

        for (int counter = 0; counter < 10; counter++)
        {
            if (chkUseThreading.Checked)
            {
                TestRunResult runResult = new TestRunResult(counter + 1);
                TestInfo tInfo = new TestInfo(conn, comm, runResult);

                if (threads[threadCounter] != null)
                {
                    // If this is here, then it will continue looping....otherwise, it hangs on the 3rd loop
                    MessageBox.Show(threads[threadCounter].ThreadState.ToString());

                    while (threads[threadCounter].IsAlive || threads[threadCounter].ThreadState == ThreadState.Running)
                        Thread.Sleep(1);

                    threads[threadCounter] = null;
                }

                // ExecuteTest is a non-static method
                threads[threadCounter] = new Thread(new ThreadStart(delegate { ExecuteTest(tInfo); }));
                threads[threadCounter].Name = "PerformanceTest" + (counter + 1);

                try
                {
                    threads[threadCounter].Start();

                    if ((threadCounter + 1) == threadCount)
                        threadCounter = 0;
                    else
                        threadCounter++;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

                Application.DoEvents();
            }
        }

            while (true)
            {
                int threadsFinished = 0;

                for (int counter = 0; counter < threadCount; counter++)
                {
                    if (!threads[counter].IsAlive || threads[counter].ThreadState == ThreadState.Stopped)
                        threadsFinished++;
                }

                if (threadsFinished == threadCount)
                    break;
                else
                    Thread.Sleep(1);
            }

您可以发布run()的一段代码吗?Thread.currentThread().notifyAll()是否有帮助?可能是每个线程都在等待其他线程执行导致死锁的操作?

我假设你说的是“Run()”,你说的是“ExecuteTask()”…我将它添加到原始帖子中。我需要查找thread.CurrentThread().NotifyAll(),因为我从未见过/听说过。他指的是wait/notify机制/模式,但它将Java和.NET混为一谈。在Java平台上,对象类(请注意,不是Thread类)提供wait()、notify()和notifyAll()。这组方法可用于实现线程间信令。NET Framework中相应的方法集可以在System.Threading.Monitor(Wait、Pulse和Pulsel)中找到。您真正想做什么?当问题到达第三个循环时,很难阅读它,ThreadState永远不会从“running”更改,或者IsAlive属性永远不会从“true”更改,因此它永远不会开始处理第三个循环。我的while循环是用来检查这些值的,它似乎没有任何帮助,程序只是停在那里,我不得不终止应用程序。我问你的意图是什么?类似于
我想用两个线程运行ExecuteTest 10次
等等。对不起,是的,这正是我想做的……使用两个独立线程运行循环10次,以加快完成速度,同时在我的SQL Server上增加更大的负载。哎哟。您正在另一个线程上调用
Application.DoEvents()
?在主线上已经够邪恶的了。
        private void ExecuteTest(object tInfo)
    {
        TestInfo testInfo = tInfo as TestInfo;

        Exception error = null;
        DateTime endTime;
        TimeSpan duration;
        DateTime startTime = DateTime.Now;

        try
        {
            if (testInfo.Connection.State != ConnectionState.Open)
            {
                testInfo.Connection.ConnectionString = connString;
                testInfo.Connection.Open();
            }

            testInfo.Command.ExecuteScalar();
        }
        catch (Exception ex)
        {
            error = ex;
            failedCounter++;

            //if (chkCancelOnError.Checked)
            //    break;
        }
        finally
        {
            endTime = DateTime.Now;
            duration = endTime - startTime;
            RunTimes.Add(duration);

            testInfo.Result.StartTime = startTime;
            testInfo.Result.EndTime = endTime;
            testInfo.Result.Duration = duration;
            testInfo.Result.Error = error;
            TestResults.Add(testInfo.Result);

            // This part must be threadsafe...
            if (lvResults.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(ExecuteTest);
                this.Invoke(d, new object[] { tInfo });
            }
            else
            {
                lvResults.Items.Add(testInfo.Result.ConvertToListViewItem());

                #region Update Results - This wouldn't work in it's own method in the threaded version
                const string msPrefix = "ms";

                // ShortestRun
                TimeSpan shortest = GetShortestRun(RunTimes);
                tbShortestRun.Text = shortest.TotalMilliseconds + msPrefix;

                // AverageRun
                TimeSpan average = GetAverageRun(RunTimes);
                tbAverageRun.Text = average.TotalMilliseconds + msPrefix;

                // MeanRun
                TimeSpan mean = GetMeanRun(RunTimes);
                tbMeanRun.Text = mean.TotalMilliseconds + msPrefix;

                // LongestRun
                TimeSpan longest = GetLongestRun(RunTimes);
                tbLongestRun.Text = longest.TotalMilliseconds + msPrefix;

                // ErrorCount
                int errorCount = GetErrorCount(TestResults);
                tbErrorCount.Text = errorCount.ToString();
                #endregion
            }

            testInfo.Command.Dispose();

            Application.DoEvents();
        }
    }