Программа написана на C #.Он последовательно получает данные из концентратора событий и создает запись в sql db.
Чтобы улучшить производительность, я сделал sql insert async.
На моем локальном компьютере, 8 ГБ оперативной памяти и 4 ядра, асинхронная версия кода работает быстрее, чем версия синхронизации.
Где, как в Dev сервере / среде (одноядерный, 1,75 ГБ).Асинхронная версия работает медленнее, чем синхронная версия.
Я увеличил масштаб сервера / среды разработки (2 ядра, 3,5 ГБ).Асинхронная версия улучшена, но по-прежнему работает медленнее, чем синхронная версия.
Насколько я понимаю, независимо от ядер процессора и размера оперативной памяти, асинхронная версия должна работать лучше, чем версия синхронизации.
Ваши мысли по этому поводу?
Фрагмент кода
// Метод 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;
}
}