发送异步天蓝色事件中心数据方法
send async azure event hub data method
在我的 api (c#) 中,我目前正在回答很多请求(每秒 15-20 个)。现在我想出于某些目的将数据发送到事件中心。但我不想延迟用户将数据发送到 azure 事件中心。所以我需要向事件中心发出异步请求,因为当我的应用程序将数据发送到 azure 时,我不想让用户等待我的回答。我需要尽快发送响应,天蓝色可能会持续 2-3 秒。
我怎样才能成功呢?
我做了 smth 但没有得到我想要的。我的代码:
public static async Task<string> SendEvents(List<object> messages)
{
string eventHubName = "rcmds";
var connectionString = GetServiceBusConnectionString();
CreateEventHub(eventHubName, connectionString);
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
try
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < messages.Count; i++)
{
var serializedMessage = JsonConvert.SerializeObject(messages[i]);
EventData data = new EventData(Encoding.UTF8.GetBytes(serializedMessage));
// Mesajları Event Hub a yolla
tasks.Add(eventHubClient.SendAsync(data));
}
Task.WaitAll(tasks.ToArray());
System.Threading.Thread.Sleep(7000);
}
catch (Exception ex)
{
new ExceptionHandler(ex, "Event Hub Library Sender - SendEvents");
}
finally
{
eventHubClient.CloseAsync().Wait();
}
return "";
}
我这样称呼这个方法:
static async void method()
{
List<object> list = new List<object>();
list.Add("dogrudur");
await Utilities.EventHub.Sender.SendEvents(list);
}
如您所见,有 "thread.sleed" 代码,但我等了 7 秒 :/
我认为您需要更多地了解如何以良好的方式真正使用 async/await。您将异步代码与阻塞代码混合在一起。
正确的代码应该是这样的:
public static async Task<string> SendEvents(List<object> messages)
{
string eventHubName = "rcmds";
var connectionString = GetServiceBusConnectionString();
CreateEventHub(eventHubName, connectionString);
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
try
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < messages.Count; i++)
{
var serializedMessage = JsonConvert.SerializeObject(messages[i]);
EventData data = new EventData(Encoding.UTF8.GetBytes(serializedMessage));
// Mesajları Event Hub a yolla
tasks.Add(eventHubClient.SendAsync(data));
}
await Task.WhenAll(tasks.ToArray());
System.Threading.Thread.Sleep(7000);
}
catch (Exception ex)
{
new ExceptionHandler(ex, "Event Hub Library Sender - SendEvents");
}
finally
{
await eventHubClient.CloseAsync();
}
return "";
}
调用代码应该是:
static async Task method()
{
List<object> list = new List<object>();
list.Add("dogrudur");
await Utilities.EventHub.Sender.SendEvents(list);
}
现在回到问题。当前代码一直等到所有消息都发送到事件中心,然后休眠 7 秒。在调用方法中,您等待 SendEvents
方法,因此您的应用程序当然需要 7 秒 + 将数据发送到事件中心所需的时间。
您可以做的是实施某种即发即弃机制。去掉代码中的Thread.Sleep
,修改调用方式为:
static void method()
{
List<object> list = new List<object>();
list.Add("dogrudur");
Utilities.EventHub.Sender.SendEvents(list);
}
该方法现在将不再等待继续,但在 return 中您将永远不知道事件发送何时完成。一般来说,应该避免使用即弃即弃的方法。
您可以采取的另一个提高性能的重要步骤是批量发送事件。目前每个事件都是使用 eventHubClient.SendAsync
发送的,但也有一种 eventHubClient.SendBatchAsync
方法 (https://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.eventhubclient.sendbatchasync.aspx),因此您可以发送比包含多个事件更少的大消息,而不是发送大量小消息.请注意,虽然有最大消息大小。
有关使用批处理发送事件的示例实现,请参阅此文件 https://github.com/DeHeerSoftware/SemanticLogging.EventHub/blob/master/SemanticLogging.EventHub/EventHubAmqpSink.cs
中的方法 private async Task SendAutoSizedBatchAsync(IEnumerable collection)
在我的 api (c#) 中,我目前正在回答很多请求(每秒 15-20 个)。现在我想出于某些目的将数据发送到事件中心。但我不想延迟用户将数据发送到 azure 事件中心。所以我需要向事件中心发出异步请求,因为当我的应用程序将数据发送到 azure 时,我不想让用户等待我的回答。我需要尽快发送响应,天蓝色可能会持续 2-3 秒。
我怎样才能成功呢? 我做了 smth 但没有得到我想要的。我的代码:
public static async Task<string> SendEvents(List<object> messages)
{
string eventHubName = "rcmds";
var connectionString = GetServiceBusConnectionString();
CreateEventHub(eventHubName, connectionString);
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
try
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < messages.Count; i++)
{
var serializedMessage = JsonConvert.SerializeObject(messages[i]);
EventData data = new EventData(Encoding.UTF8.GetBytes(serializedMessage));
// Mesajları Event Hub a yolla
tasks.Add(eventHubClient.SendAsync(data));
}
Task.WaitAll(tasks.ToArray());
System.Threading.Thread.Sleep(7000);
}
catch (Exception ex)
{
new ExceptionHandler(ex, "Event Hub Library Sender - SendEvents");
}
finally
{
eventHubClient.CloseAsync().Wait();
}
return "";
}
我这样称呼这个方法:
static async void method()
{
List<object> list = new List<object>();
list.Add("dogrudur");
await Utilities.EventHub.Sender.SendEvents(list);
}
如您所见,有 "thread.sleed" 代码,但我等了 7 秒 :/
我认为您需要更多地了解如何以良好的方式真正使用 async/await。您将异步代码与阻塞代码混合在一起。
正确的代码应该是这样的:
public static async Task<string> SendEvents(List<object> messages)
{
string eventHubName = "rcmds";
var connectionString = GetServiceBusConnectionString();
CreateEventHub(eventHubName, connectionString);
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
try
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < messages.Count; i++)
{
var serializedMessage = JsonConvert.SerializeObject(messages[i]);
EventData data = new EventData(Encoding.UTF8.GetBytes(serializedMessage));
// Mesajları Event Hub a yolla
tasks.Add(eventHubClient.SendAsync(data));
}
await Task.WhenAll(tasks.ToArray());
System.Threading.Thread.Sleep(7000);
}
catch (Exception ex)
{
new ExceptionHandler(ex, "Event Hub Library Sender - SendEvents");
}
finally
{
await eventHubClient.CloseAsync();
}
return "";
}
调用代码应该是:
static async Task method()
{
List<object> list = new List<object>();
list.Add("dogrudur");
await Utilities.EventHub.Sender.SendEvents(list);
}
现在回到问题。当前代码一直等到所有消息都发送到事件中心,然后休眠 7 秒。在调用方法中,您等待 SendEvents
方法,因此您的应用程序当然需要 7 秒 + 将数据发送到事件中心所需的时间。
您可以做的是实施某种即发即弃机制。去掉代码中的Thread.Sleep
,修改调用方式为:
static void method()
{
List<object> list = new List<object>();
list.Add("dogrudur");
Utilities.EventHub.Sender.SendEvents(list);
}
该方法现在将不再等待继续,但在 return 中您将永远不知道事件发送何时完成。一般来说,应该避免使用即弃即弃的方法。
您可以采取的另一个提高性能的重要步骤是批量发送事件。目前每个事件都是使用 eventHubClient.SendAsync
发送的,但也有一种 eventHubClient.SendBatchAsync
方法 (https://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.eventhubclient.sendbatchasync.aspx),因此您可以发送比包含多个事件更少的大消息,而不是发送大量小消息.请注意,虽然有最大消息大小。
有关使用批处理发送事件的示例实现,请参阅此文件 https://github.com/DeHeerSoftware/SemanticLogging.EventHub/blob/master/SemanticLogging.EventHub/EventHubAmqpSink.cs
中的方法private async Task SendAutoSizedBatchAsync(IEnumerable collection)