開發者在本地調試正常的 C# 多線程程序,部署到服務器後報錯「未將對象引用設置到對象的實例」(NullReferenceException)。代碼涉及 Entity Framework(EF)操作數據庫,在線程中調用 BLL 層方法寫入數據。本文分析常見原因並給出排查方向。
private bool SaveData(float[] dispVal, ClientDto client) {
ExtHost h;
BLL.ExtHostBLL host = new ExtHostBLL();
h = host.GetHostByHostcode(client.HostId);
int channelIndex = 1;
string channelId = "";
foreach (decimal val in dispVal) {
if (!host.ExistChannel("通道" + channelIndex, h.Id, out channelId)) {
channelId = Common.Result.GetNewId();
host.AddChannel(channelId, "通道" + channelIndex, client.HostId);
}
host.AddChannelData(Common.Result.GetNewId(), channelId, val);
channelIndex++;
}
return true;
}
提示:未將對象引用設置到對象的實例
這與服務器環境無關,純屬代碼邏輯或依賴注入問題。 常見原因包括:
host.GetHostByHostcode(client.HostId) 查無數據返回 null,後續調用 h.Id 拋出異常。ExtHostBLL 構造函數中若依賴 DbContext、Repository 等未正確注入(特別是多線程下 DbContext 生命周期管理不當),會導致內部字段為 null。DbContext 非線程安全。若多線程共用同一實例,或未在線程內創建新實例,極易出現併發異常或空引用。h = host.GetHostByHostcode(client.HostId);
if (h == null) { log.Error("Host not found: " + client.HostId); return false; }
using (var ctx = new MyDbContext()) 創建並銷毀,不要跨線程共享。new。ex.ToString()),而非僅 ex.Message。結論:不要怪服務器環境,先在本地模擬併發、模擬數據缺失場景單元測試,補全空值判斷與線程隔離,問題自然迎刃而解。