-1

编辑以便更好地理解...

我有一个 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();
}

类.cs

public void myFunc()
{
    foreach (string Client in Clients)
    {
           // Do something
           // Return Client and insert into listview, richtextbox, W/E
    }
} 
4

3 回答 3

1

您可以(ab)使用BackgroundWorker.ReportProgress它并将您的值作为第二个参数传递。

于 2012-09-18T14:55:41.570 回答
1

扩展 Daniel Hilgarth 的回答:如果 BGW 不存在于上下文中,Class.cs您不能将其作为参数传递,以便您可以更新进度。在您的 DoWork 签名中,这object sender是您要转换为 BackgroundWorker 以发送到的 BGW myFunc

所以你会有

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];
    }

}

为了确保线程安全,我使用扩展方法进行控件。将这个逻辑包含在扩展方法中真的很棒。每当您需要调用它时,您无需考虑 Invoke 结构,您只需调用它即可。

并确保在使用实例化 BackgroundWorker 时将它们联系在一起

bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
于 2012-09-18T15:23:18.153 回答
0

首先,确保您确实需要多线程。在列表加载完成之前,您可能只需阻止 GUI 更新即可。

如果您确实需要多线程,请确保您的三个循环需要按该顺序运行。如果不是,那么您需要 3 个 bgWorkers 而不是 1 个。

最后,还有很多关于线程安全的好文章。你会发现你不能直接更新列表视图,你必须使用线程安全的委托。

于 2012-09-18T15:05:34.447 回答