我正在做秒表,我想在某种竞争中使用它。我想开始我的秒表,点击按钮1,以便第一个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();
}发布于 2013-11-24 23:40:19
如果您的要求是:
下面的代码是如何使上述需求正常工作的基本示例。它利用了PlaySync方法SoundPlayer、BackgroundWorker (将标签上的值更新为经过的秒)和秒表来实际记录经过的时间。这肯定不是实现这一目标的最佳方式,但它应该为您提供一个起点。
需要注意的是,不能从与创建标签的线程(通常是UI线程)不同的线程更新标签。因此,如果您试图从另一个线程更新标签的文本,则需要使用label .Invoke方法(参见下面代码中的ThreadSafeUpdateLabel方法)。
这段代码没有考虑到垃圾邮件单击“开始”按钮的情况(只要单击“开始”按钮,它就会播放声音多次),用户界面也会在单击“开始”按钮时冻结。我将把解决这些问题作为代码的自然扩展留给您。
总之,在密码上:
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();
}
}https://stackoverflow.com/questions/20181973
复制相似问题