简体   繁体   English

等待事件完成,然后再次触发

[英]Awaiting an event to complete before it gets fired again

I have the following scenario, I have an event that keeps on receiving xml's that need to be pushed into DB, the pushing code and event looks something like below : 我有以下情况,我有一个继续接收需要推送到数据库的xml的事件,推送代码和事件如下所示:

async void signalrClient_OnXMLReceived(object value, MessageResponseEventArgs e)
{
    await SaveXML();
}

async task SaveXML(string xmlDoc)    
{    
    await SaveCustomer(GetCustomerDataFrmXML(xmlDoc));
    await SavePlantInfo(GetPlantDataFrmXML(xmlDoc))

   if(NotJobexists(GetJob(xmlDoc))
   {
    await SaveJob(GetJobInfo(xmlDoc))
   }
}

The problem is as soon as I encounter the first await in the save method, the control is taken back to the event where it receives new xml and calls save again, so My question is , how do I make sure that I execute all the code in the save method before the event gets fired again. 问题是我在save方法中遇到第一次等待时,该控件立即返回到它接收新xml并再次调用save的事件,所以我的问题是,如何确保执行所有代码在事件再次触发之前在save方法中单击。

I do not have control over the event when it gets called, but as and when it calls I want to make sure that I handle the event fully before it gets called next time, how can I do it? 调用该事件时,我无法控制该事件,但是在调用该事件时,我想确保在下次调用该事件之前完全处理该事件,该怎么办?

UPDATE : Thanks all for your reply, The reason why I wanted to handle the event fully before it gets fired again is, if I get one more xml which is similar to the first one in the event, I was actually inserting both which will cause the duplicate entries in DB due to the async nature, finally I reordered my saves and checked if duplicate exists before couple of await save methods. 更新:感谢您的答复,我想在再次触发该事件之前完全处理该事件的原因是,如果我又得到一个与事件中的第一个类似的xml,则实际上我插入了这两个都会导致由于异步性质,数据库中的重复项最终被重新排序,并在等待存储方法之前检查是否存在重复项。 This fixed the issue. 这解决了问题。 I didn't tried the queue or Recative framework suggestions as this needed to be fixed quickly. 我没有尝试过队列或Recative框架建议,因为这需要快速解决。

"..I want to make sure that I handle th event fully before it gets called next time, how can I do it?" “ ..我想确保在下次调用该事件之前能完全处理该事件,我该怎么办?”

Don't make async the method at all should meet your requirement. 根本不要使方法完全符合您的要求。

You need a Queue in the event handler, where you push XML that arrives, and you need a timer, where on every tick you get an element from that queue and save it to DB . 您需要在事件处理程序中添加一个队列 ,在其中推送到达的XML ,并需要一个计时器,在每个滴答声中,您从该队列中获取一个元素并将其保存到DB

Considering that Queue is FIFO structure, you will also maintain an order of the arrived XML s, in case it's important to you. 考虑到Queue是FIFO结构,如果对您很重要,您还将维护到达的XML顺序

Microsoft's Reactive Framework would handle this nicely for you. Microsoft的Reactive Framework将为您很好地处理此问题。

Instead of handling events in the normal way you create an observable from the event: 您可以从事件中创建一个可观察对象,而不必以常规方式处理事件:

var xmlreceiveds =
    Observable.FromEventPattern<EventHandler<MessageResponseEventArgs>>(
        h => signalrClient.OnXMLReceived += h, 
        h => signalrClient.OnXMLReceived -= h);

You can now get a steady stream of events that are guaranteed to complete before the next event comes. 现在,您可以获得源源不断的事件,这些事件一定会在下一个事件发生之前完成。

You handle then like this: 您可以这样处理:

var xmlreceiveds =
    Observable
        .FromEventPattern<EventHandler<MessageResponseEventArgs>>(
            h => signalrClient.OnXMLReceived += h, 
            h => signalrClient.OnXMLReceived -= h);

xmlreceiveds.Subscribe(ep =>
{
    SaveCustomer(GetCustomerDataFrmXML(ep.EventArgs.XmlDoc));
    SavePlantInfo(GetPlantDataFrmXML(ep.EventArgs.XmlDoc));

    if (NotJobexists(GetJob(ep.EventArgs.XmlDoc)))
    {
        SaveJob(GetJobInfo(ep.EventArgs.XmlDoc));
    }
});

You can easily make this be handled on a different thread by including an ObserveOn method call, like so: 通过包括一个ObserveOn方法调用,可以轻松地在另一个线程上处理此问题,如下所示:

var xmlreceiveds =
    Observable
        .FromEventPattern<EventHandler<MessageResponseEventArgs>>(
            h => signalrClient.OnXMLReceived += h, 
            h => signalrClient.OnXMLReceived -= h)
        .ObserveOn(Scheduler.Default);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM