C# 在线程中创建控件并加载照片异步
我有一个Windows窗体,里面有一个按钮和一个面板 单击按钮时,我正在向面板添加控件。。。我想要多少就有多少。此过程正在使用任务工厂。例如: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();
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实现这一点?