我正在做我的大学项目。使用的主要要求之一multithreading
(用户可以选择线程号)。
我是C#的新手,基于互联网研究。我选择ThreadPool
。
我花了很多时间观察线程在VS中使用并行监视的行为,我不知道这是如何工作的。例如,threadNumber = 10
但是并行监视仅显示4个激活的线程。
这是我的代码:
public void calculateBeta()
{
var finished = new CountdownEvent(1);
for (int i = 0; i < threadNumber; i++)
{
finished.AddCount();
ThreadPool.QueueUserWorkItem(
(state) =>
{
try
{
doSth();
}
finally
{
finished.Signal();
}
});
}
finished.Signal();
finished.Wait();
}
我究竟做错了什么?我尝试使用许多不同的线程号值测试此代码,但该代码无法正常工作。
编辑:
private void myTask(object index)
{
int z = (int)index;
double[] result = countBeta(createTableB(z), createTableDiagonalA(z));
int counter = 0;
if ((rest != 0) && (z == threadNumber - 1))
{
for (int j = z * numbersInRow; j < (z + 1) * numbersInRow + rest; j++)
{
N[j] = result[counter];
counter++;
}
}
else
{
for (int j = z * numbersInRow; j < (z + 1) * numbersInRow; j++)
{
N[j] = result[counter];
counter++;
}
}
threads[z] = true;
}
public void calculateBeta()
{
N = new double[num];
setThreadNumber(2);
checkThreadNumber();
setNumberInRow();
setRest();
threads = new bool[threadNumber];
for (int i = 0; i < threadNumber; i++)
{
Thread thread = new Thread(this.myTask);
thread.IsBackground = true;
thread.Start(i);
}
while (!checkThreads())
{
}
}
private bool checkThread()
{
bool result = true;
for (int i = 0; i < threads.Length; i++)
{
if (!threads[i])
result = false;
}
return result;
}
static void Main(string[] args)
{
Jacobi jacobi = new Jacobi();
Console.WriteLine("Metoda Jacobiego");
Console.WriteLine("Rozwiazywanie ukladu n-rownan z n-niewiadomymi Ax=b");
jacobi.getNum();
jacobi.getA();
jacobi.getB();
jacobi.calculateBeta();
jacobi.calculateM();
jacobi.calculateX();
jacobi.countNorms();
Console.ReadLine();
}
我需要来自calculateBeta的结果才能进行进一步的计算。有时线程还没有完成,但是程序前进了而没有线程需要提供的数据。我现在正在使用bool变量,但是这种解决方案不是一种很好的解决方案(创建bool表,检查是否所有线程都已完成)如何用不同的方式进行管理?
这是因为您正在使用ThreadPool来管理线程。它将基于许多因素创建一定数量的线程。您可以调整一些设置,但是总体上来说,当您承诺使用ThreadPool管理线程时,您将提交到黑盒。请查看GetMaxThreads和GetMinThreads以及与它们对应的setter方法,以了解一些选项。
在MSDN上查看此ThreadPool体系结构文章。它为班级的方式和原因提供了良好的背景。但是在介绍性段落中,您将看到以下句子,这是您遇到难题的关键:
线程池主要用于减少应用程序线程的数量并提供对工作线程的管理。
如果要控制在快速连续启动10个线程的位置,则应避免使用ThreadPool并自己管理线程。这是一个简单的,绝对最小的示例,它启动了十个线程,并且还向每个线程传递不同的数据,在本例中为索引:
void ButtonClickHandlerOrSomeOtherMethod()
{
for (int i=1; i<=10; i++) // using a 1-based index
{
new Thread(ThreadTask).Start(i);
}
}
void ThreadTask(object i)
{
Console.WriteLine("Thread " + i + " ID: " + Thread.CurrentThread.ManagedThreadId);
}
和一些示例输出:
线程1 ID:19 线程2 ID:34 线程3 ID:26 线程4的ID:5 线程5 ID:36 线程6 ID:18 线程7 ID:9 线程8 ID:38 线程9 ID:39 线程10 ID:40
后续代码演示与线程同步并“等待”,直到它们全部完成:
void ButtonClickHandlerOrSomeOtherMethod()
{
// need a collection of threads to call Join after Start(s)
var threads = new List<Thread>();
// create threads, add to List and start them
for (int i=1; i<=10; i++) {
var thread = new Thread(ThreadTask);
threads.Add(thread);
// a background thread will allow main app to exit even
// if the thread is still running
thread.IsBackground = true;
thread.Start(i);
}
// call Join on each thread which makes this thread wait on
// all 10 other threads
foreach (var thread in threads)
thread.Join();
// this message will not show until all threads are finished
Console.WriteLine("All threads finished.");
}
void ThreadTask(object i)
{
Console.WriteLine("Thread " + i + " ID: " + Thread.CurrentThread.ManagedThreadId);
// introducing some randomness to how long a task "works on something"
Thread.Sleep(100 * new Random().Next(0, 10));
Console.WriteLine("Thread " + i + " finished.");
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句