CefSharp的最小示例和多线程

时间:2015-02-23 12:26:37

标签: c# wpf multithreading xaml

我尝试在我的应用程序中实现最小的示例。在这个应用程序中,我通过以下方式调用Marketing-Windows(即ChromiumWebBrowser): 我的App.xaml.cs看起来像这样:

namespace ASA_Videowand
{
    public partial class App
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // ...
                foreach (List<string> myStrings in Screen.AllScreens.Select(myScreen => _xml.GetScreenConfigs(i)))
                {
                     // ...
                            int i1 = i;
                            List<string> strings = myStrings;
                            var newWindowThread = new Thread(() =>
                            {
                                var myMarketing = new Marketing(i1, strings[0]);
                                myMarketing.Show();
                                Dispatcher.Run();
                            });
                            newWindowThread.SetApartmentState(ApartmentState.STA);
                            newWindowThread.IsBackground = true;
                            newWindowThread.Start();
                        }
                        else
                        {
                            // ...
                        }
                    }
                    i++;
                }
            }
        }
    }
}

这是我的Marketing.xaml和Marketing.xaml.cs:

<Window x:Class="ASA_Videowand.Marketing"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:main="clr-namespace:ASA_Videowand.Views"
        Title="{Binding WebBrowser.Title}">
    <Grid>
        <main:MainView />
    </Grid>
</Window>

namespace ASA_Videowand
{
    public partial class Marketing
    {
        public Marketing(int screenNumber, string myLink)
        {
            InitializeComponent();
        }
    }
}

我的MainView.xaml:

<UserControl x:Class="ASA_Videowand.Views.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
             mc:Ignorable="d"
             d:DesignWidth="640"
             d:DesignHeight="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <cefSharp:ChromiumWebBrowser Grid.Row="0"
                                     Address="http://www.google.com"
                                     WebBrowser="{Binding WebBrowser, Mode=OneWayToSource}"
                                     Title="{Binding Title, Mode=TwoWay}" />
        <StatusBar Grid.Row="1">
            <ProgressBar HorizontalAlignment="Right"
                         IsIndeterminate="{Binding WebBrowser.IsLoading}"
                         Width="100"
                         Height="16"
                         Margin="3" />
            <Separator />
            <!-- TODO: Could show hover link URL here -->
            <TextBlock />
        </StatusBar>
    </Grid>
</UserControl>

和我的MainView.xaml.cs:

namespace ASA_Videowand.Views
{
    public partial class MainView : UserControl
    {
        public MainView()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
}

在它继续之前,它会在MainView.xaml中以exeption停止,

<cefSharp:ChromiumWebBrowser Grid.Row="0"
                                     Address="http://www.google.com"
                                     WebBrowser="{Binding WebBrowser, Mode=OneWayToSource}"
                                     Title="{Binding Title, Mode=TwoWay}" />

将属于另一个线程,因此无法修改。 我是多线程的新手。如果我使用内置的IE-WebControl尝试它,这样就可以正常工作。我知道如何从代码隐藏中调用一些东西,但在View中获取此异常对我来说是新的。 我怎样才能做到这一点?我很欣赏任何想法。感谢。

1 个答案:

答案 0 :(得分:1)

简单地说:

  

您无法在后台线程上执行UI工作

只需使用UI线程来代替您的UI工作:

foreach (List<string> myStrings in Screen.AllScreens.Select(myScreen => _xml.GetScreenConfigs(i)))
{
     // ...
            int i1 = i;
            List<string> strings = myStrings;
            var myMarketing = new Marketing(i1, strings[0]);
            myMarketing.Show();
        }
        else
        {
            // ...
        }
    }
    i++;
}