我想根据运行程序的计算机的线程数启动一些线程。
我尝试过切换,但似乎无法结束线程。
这是我的主线程并且不起作用,它表示线程在第二个开关上脱离了上下文
我可以添加任何内容,还是应该使用其他方法?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Security.Principal;
namespace Yahtzee_DataMine
{
class Program
{
public static Random diceValue = new Random();
public static int numberOfDie = new int();
public static int numberOfSides = new int();
private static System.Object lockThis = new System.Object();
public static decimal percent = new decimal();
public static ConsoleColor oldColor = Console.ForegroundColor;
static void Main(string[] args)
{
while (true)
{
getInfo();
int processorCount = Environment.ProcessorCount;
Console.WriteLine(processorCount);
if (processorCount > 7) { processorCount = 7; }
switch (processorCount)
{
case 7:
Thread Rolls6 = new Thread(Rolling2);
Rolls6.Start();
goto case 6;
case 6:
Thread Rolls5 = new Thread(Rolling3);
Rolls5.Start();
goto case 5;
case 5:
Thread Rolls4 = new Thread(Rolling4);
Rolls4.Start();
goto case 4;
case 4:
Thread Rolls3 = new Thread(Rolling5);
Rolls3.Start();
goto case 3;
case 3:
Thread Rolls2 = new Thread(Rolling6);
Rolls2.Start();
goto case 1;
case 2:
case 1:
Thread Rolls1 = new Thread(Rolling7);
Rolls1.Start();
break;
}
while (true)
{
char quit = quit = Console.ReadKey().KeyChar;
if (quit == 'q')
{
Console.WriteLine("\rTerminated");
break;
}
}
switch (processorCount)
{
case 7:
Rolls6.abort();
goto case 6;
case 6:
Rolls5.abort();
goto case 5;
case 5:
Rolls4.abort();
goto case 4;
case 4:
Rolls3.abort();
goto case 3;
case 3:
Rolls2.abort();
goto case 1;
case 2:
case 1:
Rolls1.abort();
break;
}
}
}
public static void getInfo()
{
if (WindowsIdentity.GetCurrent().Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) == false)
{
Console.WriteLine("You Are Not Running With Elevated Administrative Access.");
Console.WriteLine("Please Restart And Run Program With Administrative Access");
}
#region gettingNumberOfDie
while (true)
{
Console.WriteLine("How Many Die Would You Like To Roll? Type Q To Quit");
String howManyDie = Console.ReadLine();
try
{
int.TryParse(howManyDie, out numberOfDie);
if (numberOfDie < 2)
{
Console.WriteLine("Please Enter A Integer Greater Than 1");
continue;
}
break;
}
catch
{
Console.WriteLine("Please Enter A Number Or Press Q To Quit");
continue;
}
}
#endregion
#region gettingNumberOfSides
while (true)
{
Console.WriteLine("How Many Sides Do You Want Each Die To Have?");
String howManySides = Console.ReadLine();
try
{
int.TryParse(howManySides, out numberOfSides);
if (numberOfSides < 2)
{
Console.WriteLine("Please Enter A Integer Greater Than 1");
continue;
}
break;
}
catch
{
Console.WriteLine("Please Enter A Number Or Press Q To Quit");
continue;
}
}
#endregion
#region gettingPercent
int percentCounter = 1;
percent = (1m / (numberOfSides));
decimal percentMultiplier = percent;
while (percentCounter < numberOfDie)
{
percent = percent * percentMultiplier;
percentCounter++;
}
percent = percent * 100;
#endregion
Console.WriteLine("With " + numberOfDie + ", " + numberOfSides + " Sided Die, You Have An " + percent + '%' + " Chance of Getting A Yahtzee With Any Given Roll");
Console.WriteLine("Press Any Key To Commence");
Console.ReadKey();
}
static int seed = Environment.TickCount;
static readonly ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
public static int Rand()
{
return random.Value.Next(numberOfSides);
}
private static void Rolling1()
{
Console.WriteLine("Thread1 Started");
while (true)
{
#region rollS
Stopwatch rollTime = new Stopwatch();
rollTime.Start();
UInt64 numberOfRolls = 0;
while (true)
{
numberOfRolls++;
int counter = 0;
int[] valuesOfRoll = new int[numberOfDie];
#region Roll
while (counter < numberOfDie)
{
valuesOfRoll.SetValue((Rand() + 1), counter);
counter++;
}
#region isItYahtzee?
Boolean isItYahtzee = true;
int counterYaht = 1;
while (counterYaht < numberOfDie)
{
if (valuesOfRoll[counterYaht] != valuesOfRoll[0])
{
isItYahtzee = false;
counterYaht++;
break;
}
else
{
counterYaht++;
continue;
}
}
if ((numberOfRolls % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread1 has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
#endregion
#region ifYahtzee
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA = numberOfDie + "," + numberOfSides + "," + (numberOfDie * numberOfSides) + "," + numberOfRolls + "," + percent + "%" + "," + (percent * numberOfRolls) + "," + time + "," + timeSec + "," + (numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = (numberOfRolls).ToString();
lock (lockThis)
{
System.IO.StreamWriter fileA = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\All.txt", true);
fileA.WriteLine(linesA);
fileA.Close();
System.IO.StreamWriter fileB = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", true);
fileB.WriteLine(linesB);
fileB.Close();
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread 1");
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
#endregion
#endregion
#endregion
}
}
private static void Rolling2()
{
Console.WriteLine("Thread2 Started");
while (true)
{
#region rollS
Stopwatch rollTime = new Stopwatch();
rollTime.Start();
UInt64 numberOfRolls = 0;
while (true)
{
numberOfRolls++;
int counter = 0;
int[] valuesOfRoll = new int[numberOfDie];
#region Roll
while (counter < numberOfDie)
{
valuesOfRoll.SetValue((Rand() + 1), counter);
counter++;
}
#region isItYahtzee?
Boolean isItYahtzee = true;
int counterYaht = 1;
while (counterYaht < numberOfDie)
{
if (valuesOfRoll[counterYaht] != valuesOfRoll[0])
{
isItYahtzee = false;
counterYaht++;
break;
}
else
{
counterYaht++;
continue;
}
}
if ((numberOfRolls % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread2 has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
#endregion
#region ifYahtzee
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA = numberOfDie + "," + numberOfSides + "," + (numberOfDie * numberOfSides) + "," + numberOfRolls + "," + percent + "%" + "," + (percent * numberOfRolls) + "," + time + "," + timeSec + "," + (numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = numberOfRolls.ToString();
lock (lockThis)
{
System.IO.StreamWriter fileA = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\All.txt", true);
fileA.WriteLine(linesA);
fileA.Close();
System.IO.StreamWriter fileB = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", true);
fileB.WriteLine(linesB);
fileB.Close();
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread 2");
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
#endregion
#endregion
#endregion
}
}
private static void Rolling3()
{
Console.WriteLine("Thread3 Started");
while (true)
{
#region rollS
Stopwatch rollTime = new Stopwatch();
rollTime.Start();
UInt64 numberOfRolls = 0;
while (true)
{
numberOfRolls++;
int counter = 0;
int[] valuesOfRoll3 = new int[numberOfDie];
#region Roll
while (counter < numberOfDie)
{
valuesOfRoll3.SetValue((Rand() + 1), counter);
counter++;
}
#region isItYahtzee?
Boolean isItYahtzee = true;
int counterYaht = 1;
while (counterYaht < numberOfDie)
{
if (valuesOfRoll3[counterYaht] != valuesOfRoll3[0])
{
isItYahtzee = false;
counterYaht++;
break;
}
else
{
counterYaht++;
continue;
}
}
#endregion
if ((numberOfRolls % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread3 has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
#region ifYahtzee
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA = numberOfDie + "," + numberOfSides + "," + (numberOfDie * numberOfSides) + "," + numberOfRolls + "," + percent + "%" + "," + (percent * numberOfRolls) + "," + time + "," + timeSec + "," + (numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = numberOfRolls.ToString();
lock (lockThis)
{
System.IO.StreamWriter fileA = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\All.txt", true);
fileA.WriteLine(linesA);
fileA.Close();
System.IO.StreamWriter fileB = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", true);
fileB.WriteLine(linesB);
fileB.Close();
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread 3");
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
#endregion
#endregion
#endregion
}
}
private static void Rolling4()
{
Console.WriteLine("Thread4 Started");
while (true)
{
#region rollS
Stopwatch rollTime = new Stopwatch();
rollTime.Start();
UInt64 numberOfRolls = 0;
while (true)
{
numberOfRolls++;
int counter = 0;
int[] valuesOfRoll = new int[numberOfDie];
#region Roll
while (counter < numberOfDie)
{
valuesOfRoll.SetValue((Rand() + 1), counter);
counter++;
}
#region isItYahtzee?
Boolean isItYahtzee = true;
int counterYaht = 1;
while (counterYaht < numberOfDie)
{
if (valuesOfRoll[counterYaht] != valuesOfRoll[0])
{
isItYahtzee = false;
counterYaht++;
break;
}
else
{
counterYaht++;
continue;
}
}
#endregion
if ((numberOfRolls % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread4 has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
#region ifYahtzee
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA = numberOfDie + "," + numberOfSides + "," + (numberOfDie * numberOfSides) + "," + numberOfRolls + "," + percent + "%" + "," + (percent * numberOfRolls) + "," + time + "," + timeSec + "," + (numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = numberOfRolls.ToString();
lock (lockThis)
{
System.IO.StreamWriter fileA = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\All.txt", true);
fileA.WriteLine(linesA);
fileA.Close();
System.IO.StreamWriter fileB = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", true);
fileB.WriteLine(linesB);
fileB.Close();
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread 4");
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
#endregion
#endregion
#endregion
}
}
private static void Rolling5()
{
Console.WriteLine("Thread5 Started");
while (true)
{
#region rollS
Stopwatch rollTime = new Stopwatch();
rollTime.Start();
UInt64 numberOfRolls = 0;
while (true)
{
numberOfRolls++;
int counter = 0;
int[] valuesOfRoll = new int[numberOfDie];
#region Roll
while (counter < numberOfDie)
{
valuesOfRoll.SetValue((Rand() + 1), counter);
counter++;
}
#region isItYahtzee?
Boolean isItYahtzee = true;
int counterYaht = 1;
while (counterYaht < numberOfDie)
{
if (valuesOfRoll[counterYaht] != valuesOfRoll[0])
{
isItYahtzee = false;
counterYaht++;
break;
}
else
{
counterYaht++;
continue;
}
}
#endregion
if ((numberOfRolls % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread5 has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
#region ifYahtzee
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA = numberOfDie + "," + numberOfSides + "," + (numberOfDie * numberOfSides) + "," + numberOfRolls + "," + percent + "%" + "," + (percent * numberOfRolls) + "," + time + "," + timeSec + "," + (numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = numberOfRolls.ToString();
lock (lockThis)
{
System.IO.StreamWriter fileA = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\All.txt", true);
fileA.WriteLine(linesA);
fileA.Close();
System.IO.StreamWriter fileB = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", true);
fileB.WriteLine(linesB);
fileB.Close();
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread 5");
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
#endregion
#endregion
#endregion
}
}
private static void Rolling6()
{
Console.WriteLine("Thread6 Started");
while (true)
{
#region rollS
Stopwatch rollTime = new Stopwatch();
rollTime.Start();
UInt64 numberOfRolls = 0;
while (true)
{
numberOfRolls++;
int counter = 0;
int[] valuesOfRoll = new int[numberOfDie];
#region Roll
while (counter < numberOfDie)
{
valuesOfRoll.SetValue((Rand() + 1), counter);
counter++;
}
#region isItYahtzee?
Boolean isItYahtzee = true;
int counterYaht = 1;
while (counterYaht < numberOfDie)
{
if (valuesOfRoll[counterYaht] != valuesOfRoll[0])
{
isItYahtzee = false;
counterYaht++;
break;
}
else
{
counterYaht++;
continue;
}
}
#endregion
if ((numberOfRolls % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread6 has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
#region ifYahtzee
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA = numberOfDie + "," + numberOfSides + "," + (numberOfDie * numberOfSides) + "," + numberOfRolls + "," + percent + "%" + "," + (percent * numberOfRolls) + "," + time + "," + timeSec + "," + (numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = numberOfRolls.ToString();
lock (lockThis)
{
System.IO.StreamWriter fileA = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\All.txt", true);
fileA.WriteLine(linesA);
fileA.Close();
System.IO.StreamWriter fileB = new System.IO.StreamWriter(Directory.GetCurrentDirectory().ToString() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", true);
fileB.WriteLine(linesB);
fileB.Close();
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread 6");
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
#endregion
#endregion
#endregion
}
}
答案 0 :(得分:1)
在尝试复杂的事情之前,你真的需要学习更多C#的基础知识。你有一个非常聪明和非常基本的代码的有趣组合。您似乎已经从其他地方复制并粘贴了许多内容。
您遇到的基本问题是您在第一个Thread Rolls6 = new Thread(Rolling2);
语句的范围内声明了线程变量(switch (processorCount)
)。当谈到第二个时,这些变量不存在。您可以简单地将变量声明移到方法中更高的位置,以使它们对两者都可见,但这将是一个错误。调用Thread.Abort
是一种非常糟糕的做法。你真的需要让线程正常终止的东西。
简而言之,你的线程应该看看它们什么时候结束,他们应该做出相应的反应。
此代码的基本方式是:
private static void Rolling(CancellationToken ct)
{
while (true)
{
if (ct.IsCancellationRequested)
{
Console.WriteLine("Done with thread " + n);
break;
}
/* Do Stuff Here, But Let The Code Loop Back */
}
}
代码会不断检查CancellationToken
以查看是否已设置IsCancellationRequested
。
这是如何彻底结束一个线程。
现在我已经摆脱了所有这些Rolling{n}
方法,并用一个带有签名void Rolling(int n, int numberOfDie, int numberOfSides, double percent, CancellationToken ct)
的方法替换它们。我试图摆脱全局变量(通常很糟糕)并遵循CancellationToken
模式。
启动线程我已经获得了switch语句。线程创建现在看起来像这样:
CancellationTokenSource[] ctss =
Enumerable
.Range(1, processorCount)
.Select(n =>
{
var cts = new CancellationTokenSource();
var t = new Thread(() =>
Rolling(n, numberOfDie, numberOfSides, percent, cts.Token));
t.Start();
return cts;
})
.ToArray();
要取消代码刚刚变为的所有线程:
foreach (var cts in ctss)
{
cts.Cancel();
}
...然后ct.IsCancellationRequested
方法中的Rolling
变为真,他们将自行关闭。
这就是你应该采取的方法。
这是您的完整代码:
private static System.Object lockThis = new System.Object();
public static ConsoleColor oldColor = Console.ForegroundColor;
private static int seed = Environment.TickCount;
private static readonly ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
static void Main(string[] args)
{
var x = GetValue("How Many Die Would You Like To Roll?", 1);
if (x.HasValue)
{
var y = GetValue("How Many Sides Do You Want Each Die To Have?", 2);
if (y.HasValue)
{
int numberOfDie = x.Value;
int numberOfSides = y.Value;
double percent = 100 * Math.Pow(1.0 / numberOfSides, numberOfDie);
Console.WriteLine("With " + numberOfDie + ", " + numberOfSides + " Sided Die, You Have An " + percent + '%' + " Chance of Getting A Yahtzee With Any Given Roll");
Console.WriteLine("Press Any Key To Commence");
Console.ReadLine();
int processorCount = System.Math.Min(Environment.ProcessorCount, 8);
Console.WriteLine(processorCount);
CancellationTokenSource[] ctss =
Enumerable
.Range(1, processorCount)
.Select(n =>
{
var cts = new CancellationTokenSource();
var t = new Thread(() =>
Rolling(n, numberOfDie, numberOfSides, percent, cts.Token));
t.Start();
return cts;
})
.ToArray();
while (true)
{
string quit = Console.ReadLine().Substring(0, 1).ToUpper();
if (quit == "Q")
{
Console.WriteLine(Environment.NewLine, "Terminated");
break;
}
}
foreach (var cts in ctss)
{
cts.Cancel();
}
}
}
}
private static int? GetValue(string prompt, int minimum)
{
while (true)
{
Console.WriteLine(prompt + " Type Q To Quit");
var input = Console.ReadLine().Substring(0, 1).ToUpper();
if (input == "Q")
{
return null;
}
int output;
if (int.TryParse(input, out output))
{
if (output < minimum)
{
Console.WriteLine("Please Enter an Integer Greater Than Or Equal To " + minimum);
continue;
}
else
{
return output;
}
}
}
}
private static void Rolling(int n, int numberOfDie, int numberOfSides, double percent, CancellationToken ct)
{
Console.WriteLine("Thread" + n + " Started");
Stopwatch rollTime = Stopwatch.StartNew();
long numberOfRolls = 0;
while (true)
{
if (ct.IsCancellationRequested)
{
Console.WriteLine("Done with thread " + n);
break;
}
int[] valuesOfRoll =
Enumerable
.Range(0, numberOfDie)
.Select(x => random.Value.Next(numberOfSides) + 1)
.ToArray();
Boolean isItYahtzee = valuesOfRoll.All(x => x == valuesOfRoll[0]);
if ((numberOfRolls++ % 100000000) == 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Thread" + n + " has rolled " + numberOfRolls);
Console.ForegroundColor = oldColor;
}
if (isItYahtzee == true)
{
rollTime.Stop();
string time = rollTime.Elapsed.ToString();
string timeSec = rollTime.Elapsed.TotalSeconds.ToString();
string linesA =
String.Format(
"{0},{1},{2},{3},{4}%,{5},{6},{7},{8}",
numberOfDie,
numberOfSides,
numberOfDie * numberOfSides,
numberOfRolls,
percent,
percent * numberOfRolls,
time,
timeSec,
numberOfRolls / rollTime.Elapsed.TotalSeconds);
string linesB = (numberOfRolls).ToString();
lock (lockThis)
{
File.AppendAllLines(Directory.GetCurrentDirectory() + "\\All.txt", new[] { linesA });
File.AppendAllLines(Directory.GetCurrentDirectory() + "\\Avg_" + numberOfDie + "X" + numberOfSides + ".txt", new[] { linesB });
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(numberOfRolls + " File Has Been Successfully Save By Thread " + n);
Console.ForegroundColor = oldColor;
numberOfRolls = 0;
break;
}
}
}