发送异步天蓝色事件中心数据方法

时间:2016-06-27 13:20:22

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

在我的api(c#)中,我正在回答大量请求(一秒钟内15-20)。现在我想将数据发送到事件中心用于某些目的。但我不想延迟用户将数据发送到azure事件中心。因此我需要向事件中心发出异步请求,而我的应用程序将数据发送到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秒:/

1 个答案:

答案 0 :(得分:1)

我认为你需要更好地了解如何真正使用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)