当存在多线程 c# 时,如何在其他类中访问 Form.cs 方法

本文关键字:其他 访问 Form 方法 cs 多线程 存在 | 更新日期: 2023-09-27 17:57:23

可能的重复项:
C# Downloader:我应该使用 Threads、BackgroundWorker 还是 ThreadPool?
C#,如何到达当前线程中在其他线程中创建的内容?

所以我有以下代码

下载器.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 + ".";
    }
}

窗体1.cs/窗口窗体

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();
    }
}

我需要在没有CheckForIllegalCrossThreadCalls设置为false的情况下Form1.Instance.log = picUrl + " is downloaded to folder " + path + ".";工作,因为我听说这是做事的糟糕方式。

PS::一些代码丢失了,但我认为相关信息在那里

当存在多线程 c# 时,如何在其他类中访问 Form.cs 方法

与其

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 线程运行。

请参阅 BackgroundWorker 或 Control.Invoke 上的文档。 记住谷歌是你的朋友。