Jam*_*van 3 c# multithreading nullreferenceexception
我有一个代码块,它从队列中读取,处理一个项目(在自己的线程中),然后重复直到队列为空.
public ActionResult GetOrdersAsync() {
int count = 0;
SyncDM sync = _common.StartSync();
while (sync != null && sync.SyncId != 0) {
int customerId;
bool result = int.TryParse(sync.Payload, out customerId);
if (result) {
Task.Run(() => GetOrders(sync.SyncId, customerId));
}
count++;
//Process the next Sync
sync = _common.StartSync();
}
return Json(new JsonModel {
Message = "Started " + count + " instances of GetOrders",
Success = count > 0
});
}
Run Code Online (Sandbox Code Playgroud)
StartSync()要么从队列中删除项目,要么在队列为空时返回null.GetOrders()处理对象.
问题是有时代码在此行引发NullReferenceException Task.Run(()=> GetOrders(sync.SyncId,customerId));
在调试器中,Sync是null(异常的原因),但customerId有一个值.这告诉我同步在前一行有一个值.这让我感到困惑,我认为它与Task.Run和线程有关,但我不明白本地范围的变量如何自发地改变它的值.
sync在任务有机会对其进行操作之前,您将更新参考.请注意,任务不一定立即开始.在某些情况下,您的任务可能会在进一步执行以下操作后启动:
sync = _common.StartSync();
Run Code Online (Sandbox Code Playgroud)
现在您的引用sync可能为null,当您的任务进入访问时sync.SyncId,您将获得空引用异常.
将您的代码更改为以下内容:
if (result) {
var syncId = sync.SyncId;
Task.Run(() => GetOrders(syncId, customerId));
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为我们只想传递Id.如果你想传递对象本身怎么办?您需要创建一个不会在闭包之外修改的新变量:
if (result) {
var capturedSync = sync;
//Assuming GetOrders now takes a `Sync`
Task.Run(() => GetOrders(capturedSync, customerId));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |