我有一个项目,我需要从另一个类方法中更新标签文本。值得注意的是,此方法是从后台工作线程调用的。
我尝试在 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/