2013-11-22 89 views
1

我對WPF很陌生,並且在WPF中進行線程化,並在我的程序中成功實現了bing地圖控件。問題在於,打開控件時,控件需要很長時間來加載和減慢程序本身。加載時間從大約2秒增加到大約20秒,這是不可接受的。WPF Bing地圖控制性能低下

我的想法是,將bing地圖控件加載到單獨的線程中,從而不會降低性能。我一直在試圖做到這一點,但我的UI不斷被地圖控件的加載過程阻塞。

Here's使用調度的例子:

private init() 
{ 
    Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() 
    { 
     // Background thread: I would like to load the map here 
     Map map = new Map(); 
     map.CredentialsProvider = providerKey; 

     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
      new Action(() => 
      { 
       // Back to the UI thread 
       // How do I assign the loaded Map to this thread? 
       mapElementOnUI = map; 
       mapPanel.Children.Add(mapElementOnUI); 
      })); 
    } 
    )); 
    thread.Start(); 

    //Load the rest of the GUI here 
} 

如果我處理這樣,我得到一個InvalidOperationException(無STA線程)的線程。如果我的代碼更改爲以下,我的UI塊,而加載地圖控制:

private init() 
{ 
    Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() 
    { 
     // Background thread 

     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
      new Action(() => 
      { 
       // Back to the UI thread 
       mapElementOnUI = new Map(); 
       mapElementOnUI.CredentialsProvider = providerKey; 
       mapPanel.Children.Add(mapElementOnUI); 
      })); 
    } 
    )); 
    thread.Start(); 

    //Load the rest of the GUI here 
} 

從來就也一直在努力執行通過的await和異步沒有成功的解決方案。是否有可能在單獨的線程中加載地圖控件?有人可以用一段代碼幫我解決這個問題嗎?非常感謝!

回答

1

好,從來就現在解決了這個。 @ user1100269給出了一個很好的提示,解決了我遇到的異常:thread.SetApartmentState.STA。另外,我必須在後臺線程中創建一個新的Map實例,而不用在任何地方使用 - 我沒有真正理解,但我的問題現在已經解決。地圖在後臺加載,不會阻止用戶界面。這裏是任何人感興趣的工作代碼:

private void init() 
{ 

    Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() 
    { 
     // Background Thread 
     Map map = new Map(); 
     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
      new Action(() => 
      { 
       // Back to the UI Thread 
       var provider = new ApplicationIdCredentialsProvider(MyCredentials); 
       mapElementOnUI = new Map(); 
       mapElementOnUI.CredentialsProvider = provider; 
       mapPanel.Children.Add(mapElementOnUI); 
       updateMapLocations(); 
      })); 
    } 
    )); 
    thread.SetApartmentState(ApartmentState.STA); 
    thread.Start(); 
} 
1

那麼,在你的第二個例子你正在做的是啓動另一個線程立即切換回UI線程創建一個控制,所以這就是爲什麼你的UI阻止。

至於你的第一個例子,你不能在一個線程上創建控件並在另一個線程上使用它(這不是你得到的異常,你需要在調用Start之前調用SetApartmentState)。因此,您不能在後臺線程上創建地圖控件,然後將其加載到在主線程上創建的窗口中。這是由框架阻止的。

可以在自己的UI線程上創建一個單獨的窗口並將地圖控件加載到該窗口中。這會阻止你的主應用程序窗口被阻塞,但它會要求你管理第二個應用程序窗口。另外,如果你想讓主應用程序線程中的對象和地圖控制線程中的對象相互交互,你必須在兩端處理一堆額外的工作來處理跨線程調用。你可以閱讀關於這種方法here.

至於地圖控制本身,我不熟悉它,所以我不知道是否有其他方式來處理或推遲加載而不凍結你的用戶界面。

+0

感謝您的評論:-)它幫了我,看到我的答案,如果你有興趣... – Chris