我在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();
}
}
答案 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。