编辑以便更好地理解......
我有一个Form1.cs文件和一个单独的Class.cs文件。
在Form1
中,我有一个调用Class.myFunc()的bgWorker,这会执行三个foreach
循环,每个循环返回一些值,例如string ClientName
或string ClientOrder
我想将这些值从Class.myFunc返回到bgWorker(位于Form1
内,请记住)并将它们插入到ListView,Textbox或其他任何内容中。
所以问题是:我如何将Class.myFunc中的字符串值返回给BgWorker?
我希望有人可以帮助我...
Form1.cs的
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
ControlsHelper.ControlInvike(listProcess, () => listProcess.Items.Add("Current").Name = "item1");
myOtherClass cp = new myOtherClass();
cp.myFunc();
}
Class.cs
public void myFunc()
{
foreach (string Client in Clients)
{
// Do something
// Return Client and insert into listview, richtextbox, W/E
}
}
答案 0 :(得分:1)
你可以(ab)使用BackgroundWorker.ReportProgress
来传递你的值作为第二个参数。
答案 1 :(得分:1)
扩展Daniel Hilgarth的回答:如果在Class.cs
的上下文中不存在BGW,您不能将其作为参数传递,以便您可以更新进度。在您的DoWork签名中,object sender
是要作为BackgroundWorker投射到myFunc
的BGW。
所以你有
public void myFunc(BackgroundWorker bgw)
{
foreach (string Client in Clients)
{
// Do something
// Return Client and insert into listview, richtextbox, W/E
var returningObjects = List<string>(); //I assume this will be a list of strings based on your question.
returningObjects.Add(ClientName);
returningObjects.Add(ClientOrder);
returningObjects.Add(Client3rdThing);
bgw.ReportProgress(0,returningObjects)
}
}
比使用通用List<string>
更好,您可以创建自己的类,其中包含您需要的所有项目,然后您可以显式调用它们而不是引用列表索引。
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = sender as BackgroundWorker;
ControlsHelper.ControlInvike(listProcess, () => listProcess.Items.Add("Current").Name = "item1");
myOtherClass cp = new myOtherClass();
cp.myFunc(bgw);
}
然后在ProgressChanged事件处理程序
中private void bgWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
//Set the e.UserState to whatever you need. It is of type Object.
var returnedObjects = e.Userstate as List<string>;
if(returnedObjects != null)
{
//do stuff with each of your returnedObjects[i];
}
}
为确保线程安全,我使用this扩展方法进行控制。将这个逻辑包含在扩展方法中真的很棒。无论何时需要调用它,都不需要考虑Invoke结构,只需要调用它即可。
当您使用
实例化BackgroundWorker时,请确保将它们组合在一起bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
答案 2 :(得分:0)
首先,确保您确实需要多线程。您可能只需阻止GUI更新,直到列表加载完成为止。
如果确实需要多线程,请确保您的三个循环需要按该顺序运行。如果他们不是,那么你想要3 bgWorkers而不是1。
最后,有很多关于线程安全的好文章。您会发现无法直接更新列表视图,您必须使用线程安全代理。