我有以下代码,其中我正在尝试处理大量数据,并更新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实际上已被定义并在其使用的函数之外创建,但它是一个实例而不是静态的。
答案 0 :(得分:1)
<强>更新强>: 您好像修改了发布的源代码,所以......
您应该为每个后台线程或任务专门创建DataInterfaceClass的实例。为您的任务提供足够的输入以创建自己的实例。
话虽这么说,如果您尝试以高度并行的方式访问单个数据库中的数据,这可能会导致数据库超时。即使您可以使您的数据访问以多线程方式工作,我建议限制同时执行后台任务的数量以防止这种情况发生。
您可以使用Semaphore
(或类似)来确保同时运行的任务不超过一定数量。
答案 1 :(得分:0)
在已定义DataInterfaceClass
方法的类中为OutputData
创建一个全局实例,这样您就可以在方法中使用它。
但是,您需要谨慎使用它。如果所有线程都使用相同的实例从数据库中读取,则会导致错误。
您应该在每个线程中创建DataInterfaceClass
的新实例,或者在GetInfo
方法中实现一些锁定以避免多个访问问题。