Winform (C#) で非常に単純なプログラムを作成しています。
ただし、スレッドとタイマーに問題があります。「スレッド '' (0x1e30) がコード 0 (0x0) で終了しました」というメッセージが表示されます。これは、スレッドが正常に停止したときに発生することを読みました。しかし、これは私が望むものではありません。
番組は「今何してる?」その目的は、トレイに座って、ランダムな時間間隔 (たとえば、15 分から 120 分の間) でテキスト プロンプトが表示され、現在何をしているかを書き留めるように求めることです。これは、単純な txt ファイルに記録されます。自分がしていることを「告白」しなければならないという単純な行為が、コンピューターの前で自分の時間をどのように過ごしているかについて、より意識的になる (そしてうまくいけば、より生産的になる) という考えです。
テキスト (「Browsing StackOverflow」など) を書き込んだとき、再びトレイに最小化され、いつポップアップするかを示す新しいカウントダウンが開始されます。
問題は、何らかの理由でメインスレッドがしばらくして停止し、それによってタイマーも停止することです。理由はわかりません。Visual Studio 2012 で WinForm プロジェクトを作成するときにデフォルトで作成されるもの以外のスレッドでは何もしませんでした。
出力をログに記録すると、次のようになります (コメントを追加しました)。
- 5 // アプリがカウントダウンを開始
- 4
- 3
- 2
- 1
- 0 // タイマーが終了し、ウィンドウを表示して「Go!」を押すのを待ちます。ボタン
- 4 // 新しいカウントダウン
- 3
- 2
- 1
- 0 // ウィンドウを (意図したとおりに) 表示しない?
- 0
- スレッド '' (0x6e0) はコード 0 (0x0) で終了しました。
- 0
- 0 // など...
タイマーとスレッドに関する私の知識は、スレッド「名前なし」がその特定の瞬間に停止する理由を検出できるほど十分ではありません。
これが私のコードです (重要度の低いコードをいくつか削除しました。すべてここで確認できます: http://pastebin.com/5Apfgcpy ):
namespace WhatAreYouDoingRightNow
{
public partial class Form1 : Form
{
private string _text; // text that the user will write to
private double _timeLeft; // countdown time
public Form1()
{
InitializeComponent();
label2.Visible = true; // debug label to show timer
this.WindowState = FormWindowState.Minimized; // start minimized in tray
_text = ""; // reset text
WriteLog(true); // write for the first time of today
GetRandomTime(); // get new random time interval
timer1.Interval = 1000; // seconds
timer1.Start(); // start timer
}
// Go button (either by click or hitting Enter)
private void HitGoButton()
{
_text = DateTime.Now + " - " + textBox1.Text; // append date and time
WriteLog(false);
_text = "";
GetRandomTime();
this.WindowState = FormWindowState.Minimized;
}
// Open txt file and write to it
private void WriteLog(bool startOfTheDay)
{
// writes to a txt file using StreamWriter
}
private void GetRandomTime()
{
Random rand = new Random((int) DateTime.Now.Ticks);
_timeLeft = rand.Next(1, 2)*5; // multiplied by 60 to get minutes instead of seconds
}
// Count down to random time and then display the box
private void timer1_Tick(object sender, EventArgs e)
{
// count down
if (_timeLeft > 0)
_timeLeft--;
label2.Text = _timeLeft.ToString(); // debug label to show time
notifyIcon1.Text = _timeLeft.ToString(); // debug show time in tray
Console.WriteLine(_timeLeft); // debug write time to console window
// if time ran out --> show the window
if (_timeLeft <= 0)
{
this.WindowState = FormWindowState.Normal;
}
}
private void button1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
HitGoButton();
}
private void Form1_Resize_1(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
this.Hide(); // only show in tray icon, not in task bar
}
else if (WindowState == FormWindowState.Normal)
{
this.Show();
}
}
}
}
私のプログラムが 1 回しか動作せず、その後スレッドを終了してカウントを停止する理由を誰かが理解できますか?
前もって感謝します!
更新 1:これもデザイナー ファイルです: http://pastebin.com/yvWs2VVp
更新 2: Program.cs のコードは次のとおりです (何も変更していません)。
namespace WhatAreYouDoingRightNow
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}