2013-11-24 39 views
0

我工作的秒錶,我想在某種競爭的使用。我想通過點擊按鈕1啓動我的秒錶,以便播放第一個wav文件,然後在秒錶開始。但秒錶不啓動。這是我到現在爲止所做的。C#開始wav文件後,秒錶播放

 Stopwatch sw = new Stopwatch(); 

    private void button1_Click(object sender, EventArgs e) 
    { 
     new System.Threading.Thread(testMethod).Start(); 
    } 

    private void testMethod(object obj) 
    { 
     System.Media.SoundPlayer sp = new System.Media.SoundPlayer(@"D:\...\something.wav"); 
     sp.Play(); 

    } 

    void OnSoundPlayOver(object sender, EventArgs e) 
    { 
     timer1.Start(); 
     timer2.Start(); 
     sw.Start(); 

    } 
+2

好吧,但你有什麼問題嗎? –

+0

我忘了告訴計時器不想開始。有什麼建議麼??? – user3029389

+0

你怎麼知道的'Stopwatch'還沒有開始?是'sw.IsRunning = FALSE'和'sw.Elapsed = TimeSpan.Zero'? –

回答

0

如果你的要求是:

  • 開始按鈕,播放聲音,然後開始顯示在屏幕上經過時間的計時器。
  • 停止按鈕停止任何當前的計時器,讓屏幕上的最後一個值。
  • 在Windows窗體中實現。

以下代碼是如何獲得上述要求的基本示例。它利用SoundPlayer的PlaySync方法,BackgroundWorker(將標籤上的值更新爲流逝的秒數)以及用於實際記錄流逝時間的秒錶。絕對不是實現這一目標的最佳方式,但它應該爲您提供一個起點。

要注意的重要一點是,你不能從一個線程是從創建標籤(通常是UI線程)的線程不同更新標籤。所以,如果你想從另一個線程更新標籤的文本,你需要使用標籤.Invoke方法(見下面的代碼的ThreadSafeUpdateLabel方法)。

此代碼沒有考慮到某些垃圾郵件點擊「開始」按鈕的情況(它只是單擊播放聲音的次數),並且只要您點擊「開始」按鈕,UI就會凍結聲音發揮。我將留下解決這些問題給你作爲代碼的自然延伸。

反正到代碼:

private Stopwatch _timer = new Stopwatch(); 
private BackgroundWorker _worker; 

private void btnStop_Click(object sender, EventArgs e) 
{ 
    CancelExistingBackgroundWorker(); 
    _timer.Stop(); 
} 

private void btnStart_Click(object sender, EventArgs e) 
{ 
    CancelExistingBackgroundWorker(); 
    _timer.Reset(); 
    UpdateLabel(0); 

    _worker = new BackgroundWorker() { WorkerSupportsCancellation = true }; 
    _worker.DoWork += (a, b) => 
    { 
     while (true) 
     { 
      if ((a as BackgroundWorker).CancellationPending) return; 
      ThreadSafeUpdateLabel(); 
      Thread.Sleep(100); 
     } 
    }; 

    var soundPlayer = new SoundPlayer("wavfile.wav"); 
    soundPlayer.PlaySync(); 

    _timer.Start(); 
    _worker.RunWorkerAsync(); 
} 


private void ThreadSafeUpdateLabel() 
{ 
    if (lblElapsed.InvokeRequired) 
    { 
     lblElapsed.Invoke(new Action(() => ThreadSafeUpdateLabel())); 
    } 
    else 
    { 
     UpdateLabel(_timer.Elapsed.TotalSeconds); 
    } 
} 

private void UpdateLabel(double seconds) 
{ 
    lblElapsed.Text = seconds.ToString(); 
} 

private void CancelExistingBackgroundWorker() 
{ 
    if (_worker != null) 
    { 
     _worker.CancelAsync(); 
     _worker.Dispose(); 
    } 
}