Difference in behaviour between `DBCC TRACEON` and `QUERYTRACEON`
The query you were sending from the .NET application was still likely to be using the "old" plan (which used the legacy cardinality estimator).  

When you enabled the trace flag globally, and then removed the QUERYTRACEON hint, the query text was different, resulting in a new plan being compiled for the query.  This newly compiled plan used the newer cardinality estimator, and thus met your expectations related to the plan shape, and having results return immediately.

Changing the query text in this case had the same effect as when you added OPTION (RECOMPILE) in SSMS while doing your testing.

Regarding your follow up question in the comments:


  although I am curious, why is it that we have to do this when a trace flag is enable/disabled?


The reason for this is that enabling trace flag 2312 globally does not clear the execution plan cache.  So for queries that you need to leverage the new CE, you'll need 


to manually evict those plans from the cache one by one (with DBCC FREEPROCCACHE (plan_handle)), 
temporarily add OPTION (RECOMPILE) to them, or 
just clear the entire plan cache (if you need most queries to use the new CE, and your environment can handle this action).