2009-02-20 5 views
2

С риском звучать как полный noob, как мне реализовать ISynchronizeInvoke на System.Timers.Timer?C# ISynchronizeInvoke Вопрос

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

Пример кода:

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

ответ

3

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

0

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

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