I would compartmentalize my code into an object that can determine what should/shouldn't be done. So you would have something like this:
<cfcomponent displayname="SendGridProcessor">
<cffunction name="processEvent" access="public" returntype="void" output="false">
<cfargument name="EventData" type="struct" required="true" />
<cfswitch expression="#Arguments.EventData.Event#">
<cfcase value="processed">
<cfset processEventProcessed( Arguments.EventData ) />
</cfcase>
<cfcase value="dropped">
<cfset processEventDropped( Arguments.EventData ) />
</cfcase>
</cfswitch>
</cffunction>
<cffunction name="processEventProcessed" access="private" output="false" returntype="void">
<cfargument name="EventData" type="struct" required="true" />
<!--- do your processing --->
</cffunction>
<cffunction name="processEventDropped" access="private" output="false" returntype="void">
<cfargument name="EventData" type="struct" required="true" />
<!--- do your processing --->
</cffunction>
</cfcomponent>
This allows you to have a single method that you can call as you loop through your events, and an easy way to separate out your logic based on the event that's being passed from SendGrid.