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