可能重复:
C# Downloader: should I use Threads, BackgroundWorker or ThreadPool?
C# , how reach something in current thread that created in other thread?
所以我有以下代码
Downloader.cs
class Downloader
{
private WebClient wc = new WebClient();
public void saveImages(string picUrl, string path)
{
this.wc.DownloadFile(picUrl, path + p);
Form1.Instance.log = picUrl + " is downloaded to folder " + path + ".";
}
}
Form1.cs / Windows Form
public partial class Form1 : Form
{
static Form1 instance;
public static Form1 Instance { get { return instance; } }
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
instance = this;
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
instance = null;
}
public string log
{
set { logbox.AppendText(value); } // Logbox is Rich Text Box
}
private void ThreadJob()
{
Downloader r = new Downloader();
r.saveImages("http://c.org/car.jpg","c:/temp/");
}
private void download_Click(object sender, EventArgs e)
{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
CheckForIllegalCrossThreadCalls = false;
thread.Start();
}
}
我需要在Form1.Instance.log = picUrl + " is downloaded to folder " + path + ".";
设置为CheckForIllegalCrossThreadCalls
的情况下让false
工作,因为我听说这是做事的坏方法。
PS ::缺少部分代码,但我认为相关信息是
答案 0 :(得分:1)
saveImages
应该返回它计算的字符串值,并允许表单自行修改,而不是让void
成为saveImages
方法并修改表单:
public string saveImages(string picUrl, string path)
{
this.wc.DownloadFile(picUrl, path + p);
return picUrl + " is downloaded to folder " + path + ".";
}
现在你真正想要的是一种在后台线程中执行长时间运行任务并使用结果更新UI的方法。 BackgroundWorker
类是专门为此目的而设计的,并且在winform应用程序中比直接处理线程更容易使用。
您只需要创建BackgroundWorker
,在DoWork
事件中设置它需要执行的工作,然后在RunWorkerCompleted
事件中更新UI。
在这种情况下,DoWork
只需要调用saveImages
,然后将Result
设置为返回值,然后已完成的事件可以将Result
添加到富文本框。 BackgroundWorker
将确保UI线程运行已完成的事件。
答案 1 :(得分:1)
请参阅有关BackgroundWorker或Control.Invoke的文档。记住谷歌是你的朋友。