首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c#在播放wav文件后启动秒表

c#在播放wav文件后启动秒表
EN

Stack Overflow用户
提问于 2013-11-24 22:32:53
回答 1查看 384关注 0票数 0

我正在做秒表,我想在某种竞争中使用它。我想开始我的秒表,点击按钮1,以便第一个wav文件被播放和之后,秒表开始。但秒表还没开始。这就是我到现在为止想出来的。

代码语言:javascript
复制
        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();

    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-24 23:40:19

如果您的要求是:

  • 启动按钮,播放声音,然后启动一个计时器,显示经过的时间在屏幕上。
  • 停止按钮,停止任何当前计时器,留下屏幕上的最后一个值。
  • 在Windows窗体中实现。

下面的代码是如何使上述需求正常工作的基本示例。它利用了PlaySync方法SoundPlayer、BackgroundWorker (将标签上的值更新为经过的秒)和秒表来实际记录经过的时间。这肯定不是实现这一目标的最佳方式,但它应该为您提供一个起点。

需要注意的是,不能从与创建标签的线程(通常是UI线程)不同的线程更新标签。因此,如果您试图从另一个线程更新标签的文本,则需要使用label .Invoke方法(参见下面代码中的ThreadSafeUpdateLabel方法)。

这段代码没有考虑到垃圾邮件单击“开始”按钮的情况(只要单击“开始”按钮,它就会播放声音多次),用户界面也会在单击“开始”按钮时冻结。我将把解决这些问题作为代码的自然扩展留给您。

总之,在密码上:

代码语言:javascript
复制
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();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20181973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档