foreach (var entry in collection)
{
Devices device = DeviceService.GetInstance().GetDevices(entry.DeviceID);
string address = entry.Address;
if (address.Trim() == "")
{
address = LocationAPI.GetAddressNew(entry.OLat, entry.OLng);
}
var groupRelation = UserGroupRelationService.GetInstance().GetDeviceGroup(entry.DeviceID, model.UserID);
var profile = PersonProfileService.GetInstance().GetProfileByDevice(entry.DeviceID);
string nickname = "";
if (profile != null)
nickname = profile.Nickname ?? "";
if (groupRelation != null && device != null && model.UserID != device.UserID && !groupRelation.NickName.IsNullOrEmpty())
{
nickname = groupRelation.NickName;
}
}
var deviceService = DeviceService.GetInstance();
var groupRelationService = UserGroupRelationService.GetInstance();
var profileService = PersonProfileService.GetInstance();
Parallel.ForEach(collection, (entry) =>
{
var deviceId = entry.DeviceID;
var device = deviceService.GetDevices(deviceId);
if (device == null || model.UserID == device.UserID) return;
var address = string.IsNullOrWhiteSpace(entry.Address)
? LocationAPI.GetAddressNew(entry.OLat, entry.OLng)
: entry.Address;
var deviceGroup = groupRelationService.GetDeviceGroup(deviceId, model.UserID);
var nickname = deviceGroup != null && !string.IsNullOrWhiteSpace(deviceGroup.NickName)
? deviceGroup.NickName
: (profileService.GetProfileByDevice(deviceId)?.Nickname ?? "");
});
Key optimizations applied:
-
Parallelization with Parallel.ForEach: Replaced sequential foreach with Parallel.ForEach to process multiple items concurrently, significantly improving throughput for I/O-bound operations.
-
Service instance extraction: Moved singleton service instances outside the loop to prevent redundant instantiation on each iteration, reducing memory allocation and GC pressure.
-
Early exit conditions: Added guard clauses to skip processing when device is null or user owns the device, eliminating unnecesary operations.
-
Conditional expression simplification: Replaced verbose if-else chains with ternary operators for cleaner, more readable address and nickname assignment logic.
-
String handling improvement: Used string.IsNullOrWhiteSpace() instead of manual Trim() comparison for better readability and null safety.
-
Null-conditional operator: Leveraged ?. and ?? operators to safely access nested properties and provide default values.
When using Parallel.ForEach, ensure thread safety by avoiding modifications to shared resources within the loop body. All data access should be read-only or properly synchronized.