2013-04-10 24 views
5

我在網上搜索了幾乎所有地方,我搜索了很多次,發現瞭如此多的結果,但是我仍然無法找到解決問題的方法。如何正確使用Dispatcher.BeginInvoke?

我正在忙於將舊的WinForms應用程序轉換爲新的WPF應用程序,但我遇到了一些命令問題。在Winforms應用程序中,他們使用Control.BeginInvoke()並將其存儲在IAsyncResult對象中。我已閱讀了Dispatcher.BeginInvoke()WPF相當於Control.BeginInvoke()WinForms但是當我使用

Dispatcher.BeginInvoke()我得到這個錯誤:「無法隱式轉換類型 ‘System.Windows.Threading.DispatcherOperation’到'System.IAsyncResult'。 存在明確的轉換(你是否缺少轉換?)「。

任何幫助將不勝感激。

這是我試圖轉換的代碼。這是原始代碼WinForms。我能夠轉換除BeginInvoke部分以外的所有內容。

private eSkan.api.TeSkanAPI feSkanAPI = null; 

    private void MessageFilter_AddRemove_Invoked(bool AddFilter, IMessageFilter Filter) 
    { 
     if (AddFilter){ Application.AddMessageFilter(Filter); } 
     else { Application.RemoveMessageFilter(Filter); } 
    } 

    private void MessageFilter_AddRemove(bool AddFilter, IMessageFilter Filter) 
    { 
     { 
      IAsyncResult sr = BeginInvoke((ESKAN_ADD_REMOVE_MESSAGEFILTER)MessageFilter_AddRemove_Invoked, 
              AddFilter, Filter); 
      sr.AsyncWaitHandle.WaitOne(2000); 
     } 
    } 

下面是我的代碼,我已經轉換到目前爲止,包括我奮鬥的BeginInvoke部分。

private void MessageFilter_AddRemove_Invoked(bool addFilter, System.Windows.Forms.IMessageFilter filter) 
    { 
     if (addFilter) 
     { 
      System.Windows.Forms.Application.AddMessageFilter(filter); 
     } 
     else 
     { 
      System.Windows.Forms.Application.RemoveMessageFilter(filter); 
     } 
    } 

    private void MessageFilter_AddRemove(bool addFilter, System.Windows.Forms.IMessageFilter filter) 
    { 
     { 
      IAsyncResult sr = System.Windows.Threading.Dispatcher.BeginInvoke((ESKAN_ADD_REMOVE_MESSAGEFILTER)MessageFilter_AddRemove_Invoked, addFilter, filter); 
      sr.AsyncWaitHandle.WaitOne(2000); 
     } 
    } 

如果還有其他錯誤,請讓我知道。

感謝

+2

你可以發佈你試圖轉換的代碼嗎?看起來你在原始文件中使用了Control.BeginInvoke的返回值,但沒有看到如何,很難評論適當的變化。 – 2013-04-10 12:51:56

+0

邁克爾的答案很好 - 但值得注意的是,sr.AsyncWaitHandle.WaitOne(2000)這行只是暫停了當前線程2秒,並且看起來是多餘的(至少,我希望它是多餘的...)。如果刪除該行,則根本不需要返回值(只是回調)。 – 2013-04-10 14:41:08

+0

是的Michael的回答很好,但我仍然遇到一小部分問題。我需要爲回調使用自定義API。這是他們將BeginInvoke()分配給IAsyncResult對象的部分。我嘗試了幾種方法來使代碼正確,以便它可以執行它的功能,但我正在努力使其正確。 – GANDA1F 2013-04-11 08:34:57

回答

4

這是因爲Dispatcher.BeginInvoke,儘管它可能是等效的邏輯操作,不返回IAsyncResult,它返回一個DispatcherOperation。看看this blog post,你會看到一個關於Dispatcher如何工作的好例子。我已將相關的代碼示例複製到此處以確保它稍後存在。

public Window1() 
{ 
    InitializeComponent(); 

    CheckBox myCheckBox = new CheckBox(); 
    myCheckBox.Content = "A Checkbox"; 

    System.Threading.Thread thread = new System.Threading.Thread(
    new System.Threading.ThreadStart(
     delegate() 
     { 
     System.Windows.Threading.DispatcherOperation 
      dispatcherOp = myCheckBox.Dispatcher.BeginInvoke(
      System.Windows.Threading.DispatcherPriority.Normal, 
      new Action(
      delegate() 
      { 
       myCheckBox.IsChecked = true; 
      } 
     )); 

     dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed); 
     } 
)); 

    thread.Start(); 
} 

void dispatcherOp_Completed(object sender, EventArgs e) 
{ 
    Console.WriteLine("The checkbox has finished being updated!"); 
} 

注意爲這一行:

dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed); 

這就是你怎麼回事時,它的完成知道 - 它會通過該事件再打給你。

+0

非常感謝你的回答邁克爾。你的作品非常感謝。 – GANDA1F 2013-04-11 09:57:31

+0

我只想幫助一件事。那就是我需要將兩個不同的變量傳遞給我所調用的函數。如果不清楚,請參閱上面的代碼。 – GANDA1F 2013-04-11 09:59:00