0

我碰壁了,来到这里希望你们能帮助我解决以下问题:

我正在设计一个 wp7 应用程序,我会定期(每 700 毫秒)发出声音。我希望这些声音在 UI 线程之外的另一个线程上播放。因此,我不能使用 a dispatch timer,因为在这些声音触发的同时 UI 线程将被大量使用。

在看这个问题时,我做了一个backgroundworkerwithThread.Sleep(700)命令。这是可行的,但正如人们所预料的那样,发出声音可能需要超过 700 毫秒的时间。所以有时我会听到延迟。

backgroundworker所以我求助于你们——我怎样才能在一个或另一个线程中每 700 毫秒接近一次声音?是Timer一个明智的想法吗?

这里有一些代码可以更好地说明:

    private void RunBackgroundWorker()
    {
        backgroundWorker = new BackgroundWorker ();
        backgroundWorker.WorkerSupportsCancellation = true;
        backgroundWorker.DoWork += new DoWorkEventHandler(StartSounds); 

        backgroundWorker.RunWorkerAsync();
    }


    public void StartSounds(object sender, EventArgs e)
    {

        for (currentsoundchoice = 0; currentsoundchoice <= max; currentsoundchoice ++)
        {
            if (backgroundWorker.CancellationPending == true)
            {
                backgroundWorker.CancelAsync();
                currentsoundchoice = max + 1; //just to ensure it stops.
            }
            else
            {
                Time_Tick();
                if (max == 12)
                    currentsoundchoice = -1; //repeats the loop when it reaches max.

            }

        }
    }


    void Time_Tick()
    {
        Thread.Sleep(700);
        FrameworkDispatcher.Update();

        switch (sounds)
            case 0: //code 
                    break;
            // ETC, So forth.......
    }

我听说使用 Timer 也是解决此问题的好方法,但是是否可以在后台工作程序中运行计时器,如果可以,它的结构如何?更重要的是,它是否能让我在没有任何延迟的情况下获得尽可能接近我想要的 700 毫秒发射时间?

谢谢你。

4

1 回答 1

1

BackgroundWorker在这里是错误的选择。它旨在允许您在后台线程上执行昂贵的工作,然后将结果同步回 UI。您不需要任何同步。此外,您需要定期进行工作 - 而不是一次性的任务。

ATimer会更合适。它将允许您每 700 毫秒运行一次逻辑,并删除Thread.Sleep()当前代码中的讨厌调用。将Timer像这样做一样使用后台线程BackgroundWorker

但是请注意,它只能保证在700 毫秒过去之前不会运行。例如,如果您绝对在锤击设备,它可能很难定期运行您的代码,并且您可能会注意到延迟。

于 2012-06-10T09:13:04.360 回答