该程序用C#编写。它依次从事件中心获取数据,并输入sql db。
为了提高性能,我使sql插入异步。
在我的本地计算机8 GB内存和4核中,异步版本的代码比同步版本执行得更快。
与Dev服务器/环境中的位置相同(单核,1.75 GB)。异步版本的执行速度比同步版本慢。
我扩展了Dev服务器/环境(2个内核,3.5 GB)。异步版本已得到改进,但仍比同步版本执行得慢。
我的理解与CPU内核和内存大小无关,异步版本的性能应优于同步版本。
您对此有何想法?
代码段
//对于将从事件中心中拉出的每个事件,都将调用ManageGeoSpetialData方法。
public class EventConsumer : IEventConsumer
{
private static readonly ILog4NetService Log = new Log4NetService(MethodBase.GetCurrentMethod().DeclaringType);
private readonly IConsumerFactory _consumerFactory;
private readonly IPublisherFactory _publisherFactory;
private readonly IDataAccessLayer _dataAccess;
private IPublisher _ehPublisher;
public EventConsumer(IConsumerFactory consumerFactory, IPublisherFactory publisherFactory, IDataAccessLayer dataAccess)
{
_consumerFactory = consumerFactory;
_publisherFactory = publisherFactory;
_dataAccess = dataAccess;
}
public void Process()
{
Log.Info("CheckPointLogic Process Called ");
try
{
ManageGeoSpetialLogic("Eventhub","Eventhub");
}
catch (Exception ex)
{
Log.Error("Error in CheckPointLogic Process Method : " + ex.Message);
}
}
private void ManageGeoSpetialLogic(string consumerName, string publisherName)
{
Log.Info("Manage CheckPointLogic Called with Consumer : " + consumerName);
_ehPublisher = _publisherFactory.Get(publisherName);
var consumer = _consumerFactory.Get(consumerName);
consumer.Consume(ManageGeoSpetialData);
Log.Info("Consumer Method called ");
}
public async void ManageGeoSpetialData(object data)
{
try
{
_ehPublisher = _ehPublisher ?? _publisherFactory.Get(Apps.Terra.Messaging.Publisher.Constants.PublisherTypes.Eventhub);
GeoBoundaryEvent geoBoundaryInfo = null;
object transactionID = new object();
if (data is EventData eventInfo)
{
var value = Encoding.UTF8.GetString(eventInfo.Body.ToArray());
geoBoundaryInfo = JsonConvert.DeserializeObject<GeoBoundaryEvent>(value);
geoBoundaryInfo.SetEventType();
eventInfo.Properties.TryGetValue(EventProperties.TransactionIdProperty, out transactionID);
}
if (geoBoundaryInfo != null)
{
geoBoundaryInfo.AssetLocationTimestamp = DateTime.ParseExact(geoBoundaryInfo.AssetLocationTimestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"), "yyyy-MM-dd HH:mm:ss.fff", null);
geoBoundaryInfo.AssetLocationTimestamp = DateTime.SpecifyKind(geoBoundaryInfo.AssetLocationTimestamp, DateTimeKind.Utc);
// geoBoundaryInfo.AssetGeofenceID = _dataAccess.AddGeofenceEventInfo(geoBoundaryInfo); //Db Call
geoBoundaryInfo.AssetGeofenceID = await _dataAccess.AddGeofenceEventInfoAsync(geoBoundaryInfo);
EventData eventData = new EventData(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(geoBoundaryInfo)));
_ehPublisher.Publish(eventData); //EH publish
}
}
catch (Exception ex)
{
Log.Error($"Error in ManageGeoSpetialData {ex.Message}");
}
}
}
//Business layer method
public async Task<long> AddGeofenceEventInfoAsync(GeoBoundaryEvent geoBoundaryEvent)
{
//Need to change query for update
var query = @"INSERT INTO AssetGeofence(AssetType,AssetDSN,AssetLocationDatetime,AlertDateTime,GeoBoundaryAssetType,GeoBoundaryAssetDSN,fk_EventTypeID,GeoFenceName,GeoFenceID,IsActive) Output Inserted.AssetGeofenceID values
(@AssetType,@AssetDeviceSerialNumber,@AssetLocationTimestamp,@AlertTimestamp,@GeoBoundaryAssetType,@GeoBoundaryAssetDeviceSerialNumber,@fk_EventTypeID,@GeoFenceName,@GeoFenceId,1);";
var task = _dbConnection.ExecuteQueryAsync<long>(query, geoBoundaryEvent);
var result = await task;
return result[0];
}
//Data layer method
public async Task<List<T>> ExecuteQueryAsync<T>(string sql, object param)
{
using (var connection = GetConnection())
{
connection.Open();
var task = connection.QueryAsync<T>(sql, param, commandTimeout: 100);
await task;
var result = task.GetAwaiter().GetResult().ToList();
connection.Close();
return result;
}
}