System.Threading.Timer:为什么它恨我?

时间:2011-02-06 19:20:37

标签: c# .net winmm

我刚刚开始搞乱C#/。NET / mono和东西,我正在尝试制作一个简单的歌曲播放器。为此,我使用winmm.dll(没有找到一个简单的跨平台解决方案)。问题是:我需要更新轨迹栏以及播放的歌曲。我有两个函数Player.GetLengthPlayer.GetCurrentPosition,它们以毫秒为单位返回时间。如果我“正常”称呼它们,一切都很好。但我需要在计时器中调用它们,如下所示:

new System.Threading.Timer((state) =>
{
    length = Player.GetLength();
    pos = Player.GetCurrentPosition();
    trackBar1.Value = (pos / length) * 100;
}, null, 0, 100);     

这是GetLengthGetCurrentPosition类似:

public static int GetLength()
{
    StringBuilder s = new StringBuilder(128);
    mciSendString("status Song length", s, s.Capacity, IntPtr.Zero);
    return int.Parse(s.ToString());
}

问题:当调用这两个函数中的一个时,程序就会停止,不会抛出任何警告或异常。 注意:我使用的是.NET

所以我想知道你是否可以向我解释我错在哪里:)

1 个答案:

答案 0 :(得分:2)

我要注意的一件事是System.Threading.Timer在它自己的线程中触发它的回调。由于您正在与UI交互,因此您要么使用System.Windows.Forms.Timer(作为表单上的组件),要么调用回UI,如下所示:

new System.Threading.Timer((state) =>
{
    length = Player.GetLength();
    pos = Player.GetCurrentPosition();
    trackBar1.Invoke(new Action(()=>trackBar1.Value = (pos / length) * 100));
}, null, 0, 100);   

同样,我不确定Player类是否支持/容忍多个线程,但如果没有,则可能需要调用整个回调到UI。