2

完全な初心者のように聞こえるかもしれませんが、System.Timers.Timer に ISynchronizeInvoke を実装するにはどうすればよいですか?

mciSendString を呼び出すクラス (UI なし) があります。現在のステータスをポーリングするタイマーがあります。クラスからの呼び出しはすべて機能しますが、タイマー経過イベントからの呼び出しは機能しません。別のスレッドにあることを追跡しましたが、それ以上のことはありません。クラスと同じスレッドでデリゲートを呼び出す必要があると思いますが、まだ成功していません。

コードサンプル:

    [DllImport("winmm.dll")]
    private static extern Int32 mciSendString(string command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);

    public cPlayer()
    {
        tmrPoll = new System.Timers.Timer(1000);
        tmrPoll.Enabled = false;
        tmrPoll.Elapsed += new ElapsedEventHandler(tmrPoll_tick);
    }

    public void tmrPoll_tick(object source, ElapsedEventArgs e)
    {
        Poll();
    }

    private void Poll()
    {
        Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        tmrPoll.Stop();
        int res = 0;

        res = mciSendString("status MediaFile position", _sbBuffer, _sbBuffer.Capacity, IntPtr.Zero);
        if (res == 0) _position = int.Parse(_sbBuffer.ToString());
        if (res == 0)
        {
            Console.WriteLine("Position = " + _sbBuffer.ToString());
        } else {
            Console.WriteLine("Failed:  Error " + res.ToString());
        }

        res = mciSendString("status MediaFile length", _sbBuffer, _sbBuffer.Capacity, IntPtr.Zero);
        if (res == 0) Console.WriteLine("Length = " + _sbBuffer.ToString());
        if (res == 0) _length = int.Parse(_sbBuffer.ToString());

        res = mciSendString("status MediaFile mode", _sbBuffer, _sbBuffer.Capacity, IntPtr.Zero);
        if (res == 0) Console.WriteLine("Mode = " + _sbBuffer.ToString());
    }

    private void SendCommand(string cmd)
    {
        mciSendString(cmd, null, 0, IntPtr.Zero);
        Poll();

    }

明確にするために、SendCommand (それが何であれ、Play、Stop など) から呼び出すと、それは機能し、Poll() の結果は私が期待するものです。タイマーが起動すると、結果 (res) は 263 ですMCIERR_INVALID_DEVICE_NAME。失敗した呼び出しのスレッド ID は、成功したものとは異なるため、ISynchronizeInvoke を使用する必要があると考えました。

4

2 に答える 2

3

msdn フォーラムで回答を得ました。codeplex ( nito.async )へのリンクが記載されたメッセージを誰かが残してくれました。GenericSynchronizingObject を使用して作業を完了しました。

于 2009-02-24T04:17:11.323 に答える
0

表示されるエラー コードは何ですか? その一部は hwndCallback パラメーターに関係していると思いますが、コード サンプルを見ないとわかりません。

ただし、ここで ISynchronizeInvoke を実装する必要はありません。コールバックのウィンドウ ハンドルを渡す場合は、これを呼び出す必要がある場合があります。その場合、ISynchronizeInvoke を実装するマネージ表現で Invoke メソッドを呼び出す必要があります。つまり、ハンドルを取得したコントロール/フォームです。

于 2009-02-20T01:32:30.660 に答える