我有以下设置:
BackgroundWorker backgroundInstancesWorker = new BackgroundWorker();
backgroundInstancesWorker.DoWork += new DoWorkEventHandler(EnumerateInstances);
backgroundInstancesWorker.WorkerReportsProgress = false;
backgroundInstancesWorker.WorkerSupportsCancellation = false;
backgroundInstancesWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundInstancesWorker_RunWorkerCompleted);
// Create temporary tuple to hold the argument information
// X is type IEnumerable<Foo>, Y is type Bar
object arguments = new object[2] { X, Y };
backgroundInstancesWorker.RunWorkerAsync(arguments);
线程工作者函数:
private static void EnumerateInstances(object sender, DoWorkEventArgs e)
{
object[] arguments = e.Argument as object[];
var queryCounterSets = arguments[0] as IEnumerable<Foo>;
var sourceItem = arguments[1] as Bar;
e.Result = sourceItem;
}
最后完成的功能:
private static void backgroundInstancesWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null && e.Result is Bar)
{
// Do stuff
}
}
但是,在RunWorkerCompleted函数中,当我尝试访问e.Result对象时,它会给我TargetInvocationException并说调用线程无法访问该对象,因为另一个线程拥有它。任何人都有任何见解,为什么这是一个问题?我只想在后台线程完成后将Bar对象传递给RunWorkerCompleted。
感谢。
答案 0 :(得分:2)
您的 RunWorkerCompleted 事件处理程序应始终在访问AsyncCompletedEventArgs.Error属性之前检查AsyncCompletedEventArgs.Cancelled和RunWorkerCompletedEventArgs.Result属性。如果引发异常或操作被取消,则访问RunWorkerCompletedEventArgs.Result属性会引发异常。
您的后台功能可能发生了错误。有关处理线程仿射对象的跨线程访问的一些信息,请参阅this question。