【问题标题】:WPF Control Hosted in WinForm Blocks WinForm controls from loaded even with thread托管在 WinForm 中的 WPF 控件阻止 WinForm 控件即使使用线程也无法加载
【发布时间】:2013-05-28 23:01:17
【问题描述】:

我在 winform 中托管了 WPF 控件,其中包含菜单和一些标签。 WPF 控件连接到 Internet 以下载一些数据。 我将代码分为两个步骤 首先只需设置控件属性 第二次连接网络 第二个在线程内运行, 但是在 WPF 控件完成他的两个步骤之前,Winform 控件不会在窗体上发生。

我尝试了很多方法来使它成为线程可用的 但所有的路都去同一个目的地。

代码 1- 加载 WPF 控件

private void MDI_Load(object sender, EventArgs e)
    {
        MenuManager.FillMenu(MainMenu); // I have filled WinForm Menu first, but it doesn't appear until WPF finish

        #region = WPF Control =

        wpfManager.AddweatherControl();
        wpfManager.weatherManager.Start(); // This have to run in another thread

        #endregion
}

2- wpfManager.weatherManager.Start

    public void Start()
{
    //var tsk = System.Threading.Tasks.Task.Factory.StartNew(GetWeather);
    //tsk.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException.Message); },
    //   System.Threading.CancellationToken.None, System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted,
    //   System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());

    //System.Threading.Thread t = new System.Threading.Thread(
    //    () => weatherControl.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(GetWeather))
    //    );
    //t.SetApartmentState(System.Threading.ApartmentState.STA);
    //t.Start();

    weatherControl.Dispatcher.BeginInvoke(new Action(GetWeather), new object[] { });
}

void GetWeather()
{
    #region = Weather =
    Yweather.Getweather(UserManager.CurrentUser.Preferences.WeatherCity);

    if (Yweather.Online && Yweather.IDayForecast.Count > 0)
    {
        weatherControl.CurrentDegree.Text = Yweather.IDayForecast[0].CurrentTemperature.ToString();
        weatherControl.WeatherTypeName.Text = Yweather.IDayForecast[1].WeatherText;
        weatherControl.AllDayDegree.Text = Yweather.IDayForecast[1].LowTemperature + " - " + Yweather.IDayForecast[1].HighTemperature;
        weatherControl.WeatherType.Source = wpfManager.BitmapToImageSource(Yweather.IDayForecast[0].Image);

        xWeatherDay weatherday1 = weatherControl.OhterDaysPanel.Children[0] as xWeatherDay;
        weatherday1.AllDayDegree.Text = Yweather.IDayForecast[2].LowTemperature + " - " + Yweather.IDayForecast[2].HighTemperature;
        weatherday1.WeatherType.Source = wpfManager.BitmapToImageSource(Yweather.IDayForecast[2].Image);
    }
    else
    {
        weatherControl.CurrentDegree.Text = "0";
        weatherControl.WeatherTypeName.Text = "NAN";
        weatherControl.AllDayDegree.Text = "0 - 0";
        weatherControl.WeatherType.Source = wpfManager.BitmapToImageSource(Yweather.OfflineImage);
    }

    #endregion
}

【问题讨论】:

    标签: c# wpf wpf-controls


    【解决方案1】:

    从您发布的代码看来,延迟是由于在 UI 线程上运行 GetWeather 造成的。假设weatherControl 是 WPF 控件的一个实例,它在 UI 线程上运行,因为这是它的调度程序所属的线程。

    如果您想在后台线程上运行代码,一种简单的方法是使用BackgroundWorker。你可以像这样使用它:

    public void Start()
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (sender, args) =>
        {
            GetWeather();
            // put the results of getting the weather in to args.Result
        };
        worker.RunWorkerCompleted += (sender, args) =>
        {
            // use args.Result to update the UI
        };
        worker.RunWorkerAsync();
    }
    

    DoWork 事件处理程序中的代码在后台线程上运行,而RunWorkerCompleted 事件处理程序中的代码在 UI 线程上运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 2011-11-12
      • 2023-02-17
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多