C# 在线程中创建控件并加载照片异步

C# 在线程中创建控件并加载照片异步,c#,multithreading,winforms,async-await,C#,Multithreading,Winforms,Async Await,我有一个Windows窗体,里面有一个按钮和一个面板 单击按钮时,我正在向面板添加控件。。。我想要多少就有多少。此过程正在使用任务工厂。例如: private void ButtonClick() { // This line needs to happen on the UI thread... TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

我有一个Windows窗体,里面有一个按钮和一个面板

单击按钮时,我正在向面板添加控件。。。我想要多少就有多少。此过程正在使用任务工厂。例如:

private void ButtonClick()
{
// This line needs to happen on the UI thread...
            TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

            Task.Factory.StartNew(() =>
            {

               CustomControl.PersonResult newControl = new CustomControl.PersonResult();
               this.panel1.Controls.Add(newControl);

            }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
}
My PersonResult.cs控件具有以下布局:

控件有一个picturebox和3个标签

现在,当一个新的PersonResult控件添加到表单中时,我想执行其他后台工作程序,以便从internet获取图像并将其放入picturebox中

因此,情况是:

我多次按下按钮,立即会看到customcontrol添加到面板中,但每个控件的picturebox都将为空,但当工作人员从internet加载图像并将其放置在picturebox上时,图像将开始显示

关于如何实现这一点有什么线索吗

非常感谢

以下内容:
您不必异步添加控件。将它们添加到GUI线程中,每次创建一个新的工作线程,为其提供来自控件的委托,该委托将在工作线程完成图像加载后异步调用(使用BeginInvoke?)。

任何时候触摸控件时,都必须从UI线程执行此操作。您可以从线程/任务中实际下载图片和其他长时间运行的任务。从您的线程使用Control.Invoke调用UI线程上的委托

这篇MSDN文章提供了一个使用Control.Invoke和字符串等简单变量的好例子:

但通常会使用一个helper类,这样您就可以在代理之间传递更复杂的数据,而无需求助于大型对象数组

下面是我编写的一些示例代码:

    private void button1_Click(object sender, EventArgs e) {

        Task.Factory.StartNew(() =>
            {
                DataClass dataClass = new DataClass(this.textBox1);

                Thread.Sleep(5000); // simulate long running task

                dataClass.TextToPass = "set some text";
                dataClass.updateTargetControl();

            });
    }


    private class DataClass {
        delegate void updateTextBoxOnUiThreadDelegate();

        private TextBox _targetControl= null;
        private updateTextBoxOnUiThreadDelegate _updateDelegate; 




        internal DataClass(TextBox targetControl) {
            _updateDelegate = new updateTextBoxOnUiThreadDelegate(updateOnUiThread);
            _targetControl = targetControl;
        }

        internal string TextToPass = "";


        internal void updateTargetControl() {
            _targetControl.Invoke(_updateDelegate);
        }

        private void updateOnUiThread() {
            _targetControl.Text = this.TextToPass;
        } 

    }

我不太清楚我是否理解您为什么将UI操作包装在自己的任务中。。当它没有链接到异步任务时

无论如何。。PictureBoxes有一个LoadAsync方法。为什么要让事情变得更难

private void ButtonClick()
{
    CustomControl.PersonResult newControl = new CustomControl.PersonResult();
    this.panel1.Controls.Add(newControl);
    newControl.PictureBox.WaitOnLoad = false;
    newControl.PictureBox.LoadAsync("http://url-here.com/image.jpg");
}

//这一行发生在UI线程中…
其余的也发生在XD中。您不能从后台线程操作UI。这是用于windows窗体的吗?如何为WPF实现这一点?