在线程之间传递数据

时间:2011-01-10 11:21:02

标签: c# .net wpf multithreading c#-4.0

我有以下代码,其中我正在尝试处理大量数据,并更新UI。我使用后台工作者尝试了同样的事情,但我遇到了类似的问题。问题似乎是我正在尝试使用未在新线程上实例化的类(实际错误是当前线程不“拥有”实例)。我的问题是,是否有一种方法可以在线程之间传递此实例以避免此错误?

DataInterfaceClass dataInterfaceClass = new DataInterfaceClass();

private void OutputData(List<MyResult> Data)
{            
    progressBar1.Maximum = Data.Count;
    progressBar1.Minimum = 1;
    progressBar1.Value = 1;

    foreach (MyResult res in Data)
    {                       
        // Add data to listview
        UpdateStatus("Processing", res.Name);

        foreach (KeyValuePair<int, string> dets in res.Details)
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                // Get large amount of data from DB based on key
                // – gives error because DataInterfaceClass was
                // created in different thread.
                MyResult tmpResult = dataInterfaceClass
                    .GetInfo(dets.DataKey);

                if (tmpResult == null)
                {
                    // Updates listview
                    UpdateStatus("Could not get details", 
                        dets.DataKey); 
                }
                else
                {
                    UpdateStatus("Got Details", dets.DataKey);
                }

                progressBar1.Dispatcher.BeginInvoke(
                    (Action)(() => progressBar1.Value++));
            });
        }
    }
}

编辑:

DataInterfaceClass实际上已被定义并在其使用的函数之外创建,但它是一个实例而不是静态的。

2 个答案:

答案 0 :(得分:1)

<强>更新: 您好像修改了发布的源代码,所以......

您应该为每个后台线程或任务专门创建DataInterfaceClass的实例。为您的任务提供足够的输入以创建自己的实例。

话虽这么说,如果您尝试以高度并行的方式访问单个数据库中的数据,这可能会导致数据库超时。即使您可以使您的数据访问以多线程方式工作,我建议限制同时执行后台任务的数量以防止这种情况发生。

您可以使用Semaphore(或类似)来确保同时运行的任务不超过一定数量。

答案 1 :(得分:0)

在已定义DataInterfaceClass方法的类中为OutputData创建一个全局实例,这样您就可以在方法中使用它。

但是,您需要谨慎使用它。如果所有线程都使用相同的实例从数据库中读取,则会导致错误。

您应该在每个线程中创建DataInterfaceClass的新实例,或者在GetInfo方法中实现一些锁定以避免多个访问问题。