Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF Bing映射控制缓慢的性能_C#_Wpf_Multithreading_Bing Maps - Fatal编程技术网

C# WPF Bing映射控制缓慢的性能

C# WPF Bing映射控制缓慢的性能,c#,wpf,multithreading,bing-maps,C#,Wpf,Multithreading,Bing Maps,我对WPF和WPF中的线程非常陌生,并且在我的程序中成功地实现了bing映射控件。问题是,加载控件需要很长时间,打开时会减慢程序本身的速度。加载时间从约2秒增加到约20秒,这是不可接受的 我的想法是,在单独的线程中加载bing maps控件,从而不会降低性能。我一直在尝试这样做,但是我的UI一直被maps控件的加载过程阻塞 下面是一个使用调度器的示例: private init() { Thread thread = new System.Threading.Thread(new Sys

我对WPF和WPF中的线程非常陌生,并且在我的程序中成功地实现了bing映射控件。问题是,加载控件需要很长时间,打开时会减慢程序本身的速度。加载时间从约2秒增加到约20秒,这是不可接受的

我的想法是,在单独的线程中加载bing maps控件,从而不会降低性能。我一直在尝试这样做,但是我的UI一直被maps控件的加载过程阻塞

下面是一个使用调度器的示例:

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
}

我还尝试通过wait和async实现一个解决方案,但没有成功。是否可以在单独的线程中加载maps控件?有人能帮我写一段代码吗?非常感谢

在第二个示例中,您所做的只是启动另一个线程,该线程立即切换回UI线程以创建控件,这就是UI阻塞的原因

对于第一个示例,您不能在一个线程上创建控件并在另一个线程上使用它(这不是您得到的异常。您需要在调用Start之前调用SetApartmentState)。因此,您不能在后台线程上创建map控件,然后将其加载到主线程上创建的窗口中。框架阻止了这一点

您可以在自己的UI线程上创建一个单独的窗口,并将map控件加载到该窗口中。这将防止主应用程序窗口阻塞,但需要管理第二个应用程序窗口。此外,如果您希望主应用程序线程中的对象和映射控制线程中的对象相互交互,那么您必须做大量额外的工作来处理两端的跨线程调用。您可以阅读有关此方法的信息


至于地图控件本身,我不熟悉它,因此我不知道是否有其他方法可以在不冻结用户界面的情况下处理或延迟加载。

好的,我现在已经解决了这个问题@user1100269给出了一个很好的提示来解决我遇到的异常:thread.SetApartmentState.STA。此外,我还必须在后台线程中创建一个新的Map实例,而不必在任何地方使用它——我并没有真正做到这一点,但我的问题现在已经解决了。地图在后台加载,不再阻塞UI。以下是任何感兴趣的人的工作代码:

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();
}
谢谢你的评论:-)它帮了我的忙,如果你有兴趣,请看我的答案。。。