編輯:得到五個downvotes但沒有評論說任何關於爲什麼,我試圖重新構造這個問題。我只能假設選票是因爲人們看到很多文字,也許認爲這裏甚至沒有問題。控制檯應用程序中的奇怪問題
我寫的代碼(錯誤)表現得很奇怪。看起來代碼在其他計算機上的運行方式不同,所以如果不能重現問題,請不要生氣。
我有一個看,只是爲了好玩,在GUID中出現不同字節的頻率。我注意到,guid的字符串表示總是包含「4」。我沒有在維基百科上讀過它,而是試着去思考它可能是什麼,因爲做一點「原創性研究」並偶爾做一下自己的想法可能很有趣。 (然後再閱讀wiki!)
當我嘗試使用「突發」功能時,我的機器出現了一個奇怪的問題。如果它可以在您的環境中重現,您可以通過運行應用程序並打B來重新創建它。這應該會導致100步驟的突發(即創建100個新的guid,僅在突然,因爲寫入控制檯是非常慢)。但它實際上只有一步!
我在分配突發變量的ProcessKey()中設置了一個斷點。當我退出該方法時,我注意到在調試輸出中線程退出。這不是巧合;它每次都可靠地發生。然後,我的手錶向我顯示剛剛在上一步中分配給1000的突發變量...具有值0.
爲什麼會發生這種情況?我做錯什麼了嗎?我注意到,在指定STA的地方沒有任何屬性,但我從來沒有真正瞭解這些東西是什麼,我也沒有從我使用的控制檯應用程序模板中移除任何東西(使用VS-2011開發人員預覽,但不像Redmond I住在2012現在)...
最後:應用程序將光標移回並覆蓋文本一次又一次。如果無法使控制檯窗口足夠高以便一次顯示所有輸出,這可能無法正常工作,因此您可能想要擺弄控制檯字體(或更改控制檯的寬度,但應用程序應該相應地進行更改我沒有測試過)。模式變得完全規則(至少在我的機器上),並帶有4列輸出(如果您的控制檯寬80個字符,您將獲得4列)。
代碼重現(或沒有,視情況而定):
using System;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static bool running, exit;
static int burst;
static long guidCount = 0;
static long[] counts = new long[256];
static DateTime nextReport = DateTime.MinValue;
static readonly TimeSpan reportInterval = TimeSpan.FromSeconds(0.25);
static void Main(string[] args)
{
Console.WindowHeight = (int)(0.8*Console.LargestWindowHeight);
WriteLine(ConsoleColor.White, "X - Exit | P - Pause | S - Step (hold for Slow) | B - Burst\r\n");
WriteLine("Auto-reporting interval = {0}.", reportInterval);
Guid guid;
byte[] bytes;
var cursorPos = new CursorLocation();
while (!exit)
{
if (Console.KeyAvailable)
{
ProcessKey(Console.ReadKey(true));
}
if (running || burst > 0)
{
guid = Guid.NewGuid();
bytes = guid.ToByteArray();
++guidCount;
for (int i = 0; i < 16; i++)
{
var b = bytes[i];
++counts[b];
}
if (burst > 0) --burst;
if (burst == 0 || DateTime.Now > nextReport)
{
burst = -1;
cursorPos.MoveCursor();
ReportFrequencies();
}
}
else
Thread.Sleep(20);
}
}
static void ProcessKey(ConsoleKeyInfo keyInfo)
{
switch (keyInfo.Key)
{
case ConsoleKey.P:
running = !running;
break;
case ConsoleKey.B:
burst = 100;
break;
case ConsoleKey.S:
burst = 1;
break;
case ConsoleKey.X:
exit = true;
break;
}
}
static void ReportFrequencies()
{
Write("\r\n{0} GUIDs generated. Frequencies:\r\n\r\n", guidCount);
const int itemWidth = 9;
int colCount = Console.WindowWidth/(itemWidth*2);
for (int i = 0; i < 256; i++)
{
var f = (double)counts[i]/(16 * guidCount);
Write(RightAdjust(itemWidth, "{0:x}", i));
Write(GetFrequencyColor(f), " {0:p}".PadRight(itemWidth), f);
if ((i + 1) % colCount == 0) Write("\r\n");
}
nextReport = DateTime.Now + reportInterval;
}
static ConsoleColor GetFrequencyColor(double f)
{
if (f < 0.003) return ConsoleColor.DarkRed;
if (f < 0.004) return ConsoleColor.Green;
if (f < 0.005) return ConsoleColor.Yellow;
return ConsoleColor.White;
}
static string RightAdjust(int w, string s, params object[] args)
{
if (args.Length > 0)
s = string.Format(s, args);
return s.PadLeft(w);
}
#region From my library, so I need not include that here...
class CursorLocation
{
public int X, Y;
public CursorLocation()
{
X = Console.CursorLeft;
Y = Console.CursorTop;
}
public void MoveCursor()
{
Console.CursorLeft = X;
Console.CursorTop = Y;
}
}
static public void Write(string s, params object[] args)
{
if (args.Length > 0) s = string.Format(s, args);
Console.Write(s);
}
static public void Write(ConsoleColor c, string s, params object[] args)
{
var old = Console.ForegroundColor;
Console.ForegroundColor = c;
Write(s, args);
Console.ForegroundColor = old;
}
static public void WriteNewline(int count = 1)
{
while (count-- > 0) Console.WriteLine();
}
static public void WriteLine(string s, params object[] args)
{
Write(s, args);
Console.Write(Environment.NewLine);
}
static public void WriteLine(ConsoleColor c, string s, params object[] args)
{
Write(c, s, args);
Console.Write(Environment.NewLine);
}
#endregion
}
}
我已經運行的應用程序,並跨過(F10)的ProcessKey方法和連拍的設置是否正確。我也走了(F11),然後走出去(Shift + F11),我看到兩種情況下突發= 100。不知道你在做什麼。我應該補充一點,Guids包含了你的機器的各個方面,所以我不會期望一個統一的分佈,否則你將有機會在系統之間進行Guid碰撞。畢竟,它應該是一個全球唯一的標識符。 – Lazarus 2012-03-08 16:53:06
這些線程退出可能與調試器的活動而不是您的代碼有關嗎? – dsolimano 2012-03-08 17:07:33
謝謝。我希望有人投票會留下評論,讓我知道爲什麼。我知道**的第一句話(短而甜的「嘗試這個」)不是一個問題,並且可能使它看起來毫無疑問。但是,如果人們真正閱讀,他們會看到它有一點背景,一個具體的問題,以及許多重現結果的代碼。 – 2012-03-08 20:43:15