c# - 发送异步 Azure 事件中心数据方法

标签 c# azure asynchronous asp.net-web-api azure-eventhub

在我的 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);
        }

如您所见,有“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);
}

该方法现在将不再在继续之前等待,但作为返回,您将永远不知道事件发送何时完成。一般来说,应避免即发即忘方法。

提高性能的另一个重要步骤是批量发送事件。目前,每个事件都是使用 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)

关于c# - 发送异步 Azure 事件中心数据方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38055081/

相关文章:

c# - 如何在 Unity 中全局为类创建别名?

具有 where 条件的 C# LINQ GroupBy

java - 在 Windows Azure 上创建 Java Restful Web 服务

Angular 9,滚动恢复/ anchor 滚动不适用于异步数据加载

c - 我如何在客户端-服务器应用程序中异步发送文件?(使用 winsock2.h,在 C 中)

c# - 在 UserControl 中捕获 Esc 键

c# - Unity 5.5 废弃的粒子系统代码

azure - 如何将 UiPath Studio 与 Azure DevOps 连接?

Azure AD B2C 邀请电子邮件

java - 如何使用来自外部客户端的异步进程?