Вопрос

Рискуя показаться полным нубом, как мне реализовать ISynchronizeInvoke в системе.Таймеры.Таймер?

У меня есть класс (без пользовательского интерфейса), который выполняет вызовы mciSendString .У меня есть таймер, который должен опрашивать текущее состояние.Все вызовы из класса работают, но не те, которые поступают из события timers elapsed.Я отследил, что это было в другом потоке, но дальше этого я не продвинулся.Я думаю, мне нужно вызвать делегата в том же потоке, что и класс, но мне пока не повезло с этим.

Пример кода:

    [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.Идентификатор потока в неудачном вызове отличается от того, который выполняется успешно, вот почему я решил, что мне нужно использовать ISynchronizeInvoke .

Это было полезно?

Решение

Я получил ответ на форуме msdn.Кто-то оставил мне сообщение со ссылкой на codeplex (nito.асинхронный).Я использовал GenericSynchronizingObject для выполнения этой работы.

Другие советы

Какой код ошибки вы получаете?Я предполагаю, что частично это связано с параметром hwndCallback, но, не видя никаких примеров кода, трудно сказать.

Однако здесь вам не нужно реализовывать ISynchronizeInvoke .Возможно, вам придется вызвать его, если вы передаете дескриптор окна для обратного вызова.В этом случае вам нужно будет вызвать метод Invoke в управляемом представлении, которое реализует ISynchronizeInvoke.Другими словами, элемент управления / форма, от которого вы получили дескриптор.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top