c# - Winforms:从另一个类更新表单上的标签

标签 c# winforms multithreading label progress

我有一个项目,我需要从另一个类方法中更新标签文本。值得注意的是,此方法是从后台工作线程调用的。

我尝试在 Workers ReportProgress() 中传递文本以更新为 UserState Obj;方法,然后在主窗体上触发 worker 进度更改事件时更新标签。这行得通,但显然仅在引发进度更改事件时才更新标签文本。

我有不断加载/删除代理的代码,我需要一个标签来显示它发生的情况(而不是仅在 bg worker progress changed 事件触发时更新)。希望有人能提供帮助。

谢谢

编辑* 这里有一些代码可以使问题更容易理解:-

  public string Request(string action)
    {

        if (string.IsNullOrWhiteSpace(action))
        {
            return "";
        }

        HttpWebRequest req;

        string response = string.Empty;
        while (response.Equals(string.Empty) && proxy != null)
        {
            try
            {
                req = (HttpWebRequest)WebRequest.Create(action);
                req.Proxy = proxy;
                response = new StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd();
            }
            catch (Exception ex)
            {
                RemoveProxy(proxy);
                MessageBox.Show("Proxy Removed: " + proxy.Address.ToString());

                proxy = GenNewProx();
                MessageBox.Show("New proxy" + proxy.Address.ToString());
            }
        }

        return response;
    }

^^^ - 在我需要设置标签文本的地方,目前使用 Msgboxs,但更新主窗体上的标签显然更可取

   foreach (string url in URLs)
        {
            result.URL = url;
            result.Shares = grabber.GetFacebookShares(url);
            result.Tweets = grabber.GetTweetCount(url);
            result.PlusOnes = grabber.GetPlusOnes(url);

            bgWorker.ReportProgress((outputGridView.Rows.Count * 100) / importGridView.Rows.Count, result);
        }

^^^ - 在主窗体上的 bg workers do_work 方法中。

第二次编辑*

我对事件有点陌生,但我不能触发自定义事件说 Proxy_Changed 每次我切换代理并使用新代理/msg w.e 传递字符串参数,然后在主窗体中订阅此事件,然后在主窗体上设置标签 text = string args when this event fires off?不过,我可能在说胡言乱语:/

最佳答案

以下是我认为您类(class)中需要做背景工作的重要部分:

public class Grabber
{
    public event EventHandler<MyArgs> NotifyParentUI;

    // other code.....

    public string Request(string action)
    {
        if (string.IsNullOrWhiteSpace(action))
        {
            return "";
        }

        HttpWebRequest req;

        string response = string.Empty;
        while (response.Equals(string.Empty) && proxy != null)
        {
            try
            {
                req = (HttpWebRequest)WebRequest.Create(action);
                req.Proxy = proxy;
                response = new StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd();
            }
            catch (Exception ex)
            {
                RemoveProxy(proxy);
                NotifyParentUI(this, new MyArgs() 
                   { Message = string.Format("Proxy Removed: {0}", proxy.Address.ToString()) });

                proxy = GenNewProx();
                NotifyParentUI(this, new MyArgs() 
                   { Message = string.Format("New Proxy: {0}", proxy.Address.ToString()) });
            }
        }

        return response;
    } 
}

在您的主窗体中,您有一种更新线程安全标签的方法:

public void UpdateMyLabel(object sender, MyArgs ea)
{
    this.Invoke(new MethodInvoker(
        delegate()
        {
            labelControl1.Text = ea.Message;
        }
        ));
}

同样在主窗体中,您必须创建一个“抓取器”的实例:

Grabber grabber = new Grabber();
grabber.NotifyParentUI += UpdateMyLabel;

你应该有一个在它自己的线程上运行的方法:

public void ThreadProc()
{

    // other code before this....

    foreach (string url in URLs)
    {
       result.URL = url;
       result.Shares = grabber.GetFacebookShares(url);
       Thread.Sleep(0); // may want to take the Sleeps out
       result.Tweets = grabber.GetTweetCount(url);
       Thread.Sleep(0);
       result.PlusOnes = grabber.GetPlusOnes(url);
       Thread.Sleep(0);
    }
}

这是在主窗体部分启动线程的方法:

Thread t = new Thread(new ThreadStart(ThreadProc));
t.Start();

作为旁注,如果您需要将数据传递给您的线程,请看这里: Passing Data to Threads and Retrieving Data from Threads

关于c# - Winforms:从另一个类更新表单上的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9804498/

相关文章:

c# - 设计分布式仿真的最佳方式

c# - 将 int 值转换为渐变中的颜色

c# - 使用 DataBinding 更新标签

C# 登录示例

delphi - 递归文件搜索线程

c# - MiniProfiler、EntityFramework 代码优先和后台任务 nullreference

c# - Control.invoke 和父控件

c# - 从 C# 2.0 中的另一个线程更新控件

c# - Windows Phone C#异步获取https请求

java - 如何创建完全连接的客户端图?