如何在asyn方法中只执行一次循环,从eventhub

时间:2016-11-11 05:49:32

标签: c# asynchronous async-await

我在break方法async中尝试使用for loop,但是为了不断地从事件中心获取事件,它一次又一次地调用方法。

我想在获取data == "mytestdata"时执行一次循环。

如果它是真正的发送通知邮件,需要打破,因为我不想再发送邮件,因为我已经发送了它。

我也尝试使用isMailSend = true;,但它执行twic。

bool isMailSend = false;
async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach (EventData eventData in messages)
            {
                string data = Encoding.UTF8.GetString(eventData.GetBytes());


                if (data == "mytestdata")
                {
                    //send mail notification
                isMailSend = true;
                Console.WriteLine("mail send ");
                break;
                }

                Console.WriteLine(string.Format("Message received.  Partition: '{0}', Data: '{1}'",
                    context.Lease.PartitionId, data));
            }

            //Call checkpoint every 1 minutes, so that worker can resume processing from 1 minutes back if it restarts.
            if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(1))
            {
                await context.CheckpointAsync();
                this.checkpointStopWatch.Restart();
            }
        }

1 个答案:

答案 0 :(得分:1)

当您的ProcessEventsAsync遇到await时,控制权将返回给其调用者,以查看调用者是否仍然可以执行某些操作,直到调用者遇到await,之后控制在调用堆栈中上升以查看调用者是否有某些内容做等等。

所以你的线程看到等待。 callstack中的一个调用者没有等待,并调用ProcessEventsAsync。虽然你已经设置了isMailSent,但是你没有检查它,因此你的foreach外观是第二次输入。

按如下方式更改您的代码:

class MyClass
{

    private bool isMailSent = false;

    async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
    {
        if (this.isMailSent)
        {
             // do whatever you want to do if a 2nd call is received
             // while isMailSent
             ProcessWhileIsMailSent(...)
        }
        else
        {   // called for the first time
            foreach (EventData eventData in messages)
            {
                string data = ...
                if (data == "mytestdata")
                {
                    this.isMailSent = true;
                // etc.

效果是,当isMailSent为真,并且你的一个调用者决定给你打电话时,你的foreach不会被调用,但是(在这个例子中)ProcessWhileIsMailSent(...)

当您准备再次处理收到的输入时,不要忘记将isMailSent设置为false。

如果您是多线程,请在访问之前考虑锁定isMailSent。