发送异步azure事件中心数据方法

本文关键字:数据 方法 事件 异步 azure | 更新日期: 2023-09-27 17:52:45

在我的api (c#)中,我目前正在回答大量的请求(15-20秒)。现在我想将数据发送到事件中心用于某些目的。但是我不想延迟用户发送数据到azure事件中心。所以我需要异步请求事件中心,因为当我的应用程序发送数据到azure我不想让用户等待我的答案。我需要尽快发送响应,azure可能持续2-3秒。

我怎样才能成功呢?我做了某事,但没有得到我想要的。我的代码:

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);
        }

可以看到,有一个"线程"。"sleep"代码,但我等待了7秒:/

发送异步azure事件中心数据方法

我认为你需要学习更多关于如何以良好的方式真正使用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);
}

该方法现在将不再等待继续,但作为回报,您将永远不会知道事件发送何时完成。一般情况下,应避免使用"即火即忘"方法。

提高性能的另一个重要步骤是批量发送事件。目前,每个事件都是使用eventHubClient.SendAsync发送,但也有一个eventHubClient.SendBatchAsync方法(https://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.eventhubclient.sendbatchasync.aspx),所以,而不是发送大量的小消息,你可以发送更少的大消息比包含一个以上的事件。但是要注意,消息大小是有上限的。

有关使用批处理发送事件的示例实现,请参阅此文件中的方法private async Task SendAutoSizedBatchAsync(IEnumerable collection) https://github.com/DeHeerSoftware/SemanticLogging.EventHub/blob/master/SemanticLogging.EventHub/EventHubAmqpSink.cs