public void BatchExecuteOneResultSet() { const int resultSets = 1; ConnectionInfo ci = Common.CreateTestConnectionInfo(new[] { Common.StandardTestData }, false); // Setup: Create a callback for batch completion BatchSummary batchSummaryFromCallback = null; Batch.BatchAsyncEventHandler batchCallback = b => { batchSummaryFromCallback = b.Summary; return(Task.FromResult(0)); }; // ... Create a callback for result set completion bool resultCallbackFired = false; ResultSet.ResultSetAsyncEventHandler resultSetCallback = r => { resultCallbackFired = true; return(Task.FromResult(0)); }; // If I execute a query that should get one result set var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory); batch.BatchCompletion += batchCallback; batch.ResultSetCompletion += resultSetCallback; batch.Execute(GetConnection(ci), CancellationToken.None).Wait(); // Then: // ... It should have executed without error Assert.True(batch.HasExecuted, "The batch should have been marked executed."); Assert.False(batch.HasError, "The batch should not have an error"); // ... There should be exactly one result set Assert.Equal(resultSets, batch.ResultSets.Count); Assert.Equal(resultSets, batch.ResultSummaries.Length); // ... Inside the result set should be with 5 rows Assert.Equal(Common.StandardRows, batch.ResultSets.First().RowCount); Assert.Equal(Common.StandardRows, batch.ResultSummaries[0].RowCount); // ... Inside the result set should have 5 columns Assert.Equal(Common.StandardColumns, batch.ResultSets.First().Columns.Length); Assert.Equal(Common.StandardColumns, batch.ResultSummaries[0].ColumnInfo.Length); // ... There should be a message for how many rows were affected Assert.Equal(resultSets, batch.ResultMessages.Count()); // ... The callback for batch completion should have been fired Assert.NotNull(batchSummaryFromCallback); // ... The callback for resultset completion should have been fired Assert.True(resultCallbackFired); // We only want to validate that it happened, validation of the // summary is done in result set tests }
public void BatchExecuteInvalidQuery() { // Setup: // ... Create a callback for batch start bool batchStartCalled = false; Batch.BatchAsyncEventHandler batchStartCallback = b => { batchStartCalled = true; return(Task.FromResult(0)); }; // ... Create a callback for batch completion BatchSummary batchSummaryFromCallback = null; Batch.BatchAsyncEventHandler batchCompleteCallback = b => { batchSummaryFromCallback = b.Summary; return(Task.FromResult(0)); }; // ... Create a callback that will fail the test if it's called ResultSet.ResultSetAsyncEventHandler resultSetCallback = r => { throw new Exception("ResultSet callback was called when it should not have been."); }; ConnectionInfo ci = Common.CreateTestConnectionInfo(null, true); // If I execute a batch that is invalid var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory); batch.BatchStart += batchStartCallback; batch.BatchCompletion += batchCompleteCallback; batch.ResultSetCompletion += resultSetCallback; batch.Execute(GetConnection(ci), CancellationToken.None).Wait(); // Then: // ... It should have executed with error Assert.True(batch.HasExecuted); Assert.True(batch.HasError); // ... There should be no result sets Assert.Empty(batch.ResultSets); Assert.Empty(batch.ResultSummaries); // ... There should be plenty of messages for the error Assert.NotEmpty(batch.ResultMessages); // ... The callback for batch completion should have been fired Assert.NotNull(batchSummaryFromCallback); // ... The callback for batch start should have been fired Assert.True(batchStartCalled); }
public void QueryExecuteInvalidBatch() { // Setup: // ... Create a callback for batch start int batchStartCallbacksReceived = 0; Batch.BatchAsyncEventHandler batchStartCallback = b => { batchStartCallbacksReceived++; return(Task.FromResult(0)); }; // ... Create a callback for batch completion int batchCompletionCallbacksReceived = 0; Batch.BatchAsyncEventHandler batchCompltionCallback = summary => { batchCompletionCallbacksReceived++; return(Task.CompletedTask); }; // If: // ... I create a query from an invalid batch ConnectionInfo ci = Common.CreateTestConnectionInfo(null, true); var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Query query = new Query(Common.InvalidQuery, ci, new QueryExecutionSettings(), fileStreamFactory); query.BatchStarted += batchStartCallback; query.BatchCompleted += batchCompltionCallback; // Then: // ... I should get back a query with one batch not executed Assert.NotEmpty(query.QueryText); Assert.NotEmpty(query.Batches); Assert.Equal(1, query.Batches.Length); Assert.False(query.HasExecuted); Assert.Throws <InvalidOperationException>(() => query.BatchSummaries); // If: // ... I then execute the query query.Execute(); query.ExecutionTask.Wait(); // Then: // ... There should be an error on the batch Assert.True(query.HasExecuted); Assert.NotEmpty(query.BatchSummaries); Assert.Equal(1, query.BatchSummaries.Length); Assert.True(query.BatchSummaries[0].HasError); Assert.NotEmpty(query.BatchSummaries[0].Messages); // ... The batch callbacks should have been called once Assert.Equal(1, batchStartCallbacksReceived); Assert.Equal(1, batchCompletionCallbacksReceived); }
public void QueryExecuteMultipleBatches() { // Setup: // ... Create a callback for batch start int batchStartCallbacksReceived = 0; Batch.BatchAsyncEventHandler batchStartCallback = b => { batchStartCallbacksReceived++; return(Task.FromResult(0)); }; // ... Create a callback for batch completion int batchCompletedCallbacksReceived = 0; Batch.BatchAsyncEventHandler batchCompletedCallback = summary => { batchCompletedCallbacksReceived++; return(Task.FromResult(0)); }; // If: // ... I create a query from two batches (with separator) ConnectionInfo ci = Common.CreateTestConnectionInfo(null, false); string queryText = string.Format("{0}\r\nGO\r\n{0}", Common.StandardQuery); var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Query query = new Query(queryText, ci, new QueryExecutionSettings(), fileStreamFactory); query.BatchStarted += batchStartCallback; query.BatchCompleted += batchCompletedCallback; // Then: // ... I should get back two batches to execute that haven't been executed Assert.NotEmpty(query.QueryText); Assert.NotEmpty(query.Batches); Assert.Equal(2, query.Batches.Length); Assert.False(query.HasExecuted); Assert.Throws <InvalidOperationException>(() => query.BatchSummaries); // If: // ... I then execute the query query.Execute(); query.ExecutionTask.Wait(); // Then: // ... The query should have completed successfully with two batch summaries returned Assert.True(query.HasExecuted); Assert.NotEmpty(query.BatchSummaries); Assert.Equal(2, query.BatchSummaries.Length); // ... The batch start and completion callbacks should have been called precisely 2 times Assert.Equal(2, batchStartCallbacksReceived); Assert.Equal(2, batchCompletedCallbacksReceived); }
public async Task BatchExecuteExecuted() { ConnectionInfo ci = Common.CreateTestConnectionInfo(new[] { Common.StandardTestData }, false); // If I execute a batch var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory); batch.Execute(GetConnection(ci), CancellationToken.None).Wait(); // Then: // ... It should have executed without error Assert.True(batch.HasExecuted, "The batch should have been marked executed."); Assert.False(batch.HasError, "The batch should not have an error"); // Setup for part 2: // ... Create a callback for batch completion Batch.BatchAsyncEventHandler completeCallback = b => { throw new Exception("Batch completion callback should not have been called"); }; // ... Create a callback for batch start Batch.BatchAsyncEventHandler startCallback = b => { throw new Exception("Batch start callback should not have been called"); }; // If I execute it again // Then: // ... It should throw an invalid operation exception batch.BatchStart += startCallback; batch.BatchCompletion += completeCallback; await Assert.ThrowsAsync <InvalidOperationException>(() => batch.Execute(GetConnection(ci), CancellationToken.None)); // ... The data should still be available without error Assert.False(batch.HasError, "The batch should not be in an error condition"); Assert.True(batch.HasExecuted, "The batch should still be marked executed."); Assert.NotEmpty(batch.ResultSets); Assert.NotEmpty(batch.ResultSummaries); }
public void QueryExecuteNoOpBatch() { // Setup: // ... Create a callback for batch startup Batch.BatchAsyncEventHandler batchStartCallback = b => { throw new Exception("Batch startup callback should not have been called."); }; // ... Create a callback for batch completion Batch.BatchAsyncEventHandler batchCompletionCallback = summary => { throw new Exception("Batch completion callback was called"); }; // If: // ... I create a query from a single batch that does nothing ConnectionInfo ci = Common.CreateTestConnectionInfo(null, false); var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Query query = new Query(Common.NoOpQuery, ci, new QueryExecutionSettings(), fileStreamFactory); query.BatchStarted += batchStartCallback; query.BatchCompleted += batchCompletionCallback; // Then: // ... I should get no batches back Assert.NotEmpty(query.QueryText); Assert.Empty(query.Batches); Assert.False(query.HasExecuted); Assert.Throws <InvalidOperationException>(() => query.BatchSummaries); // If: // ... I Then execute the query query.Execute(); query.ExecutionTask.Wait(); // Then: // ... The query should have completed successfully with no batch summaries returned Assert.True(query.HasExecuted); Assert.Empty(query.BatchSummaries); }
private static void ExecuteAndCompleteQuery(string ownerUri, Query query, IEventSender eventSender, Query.QueryAsyncEventHandler querySuccessCallback, Query.QueryAsyncErrorEventHandler queryFailureCallback) { // Setup the callback to send the complete event Query.QueryAsyncEventHandler completeCallback = async q => { // Send back the results QueryCompleteParams eventParams = new QueryCompleteParams { OwnerUri = ownerUri, BatchSummaries = q.BatchSummaries }; await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams); }; // Setup the callback to send the complete event Query.QueryAsyncErrorEventHandler failureCallback = async(q, e) => { // Send back the results QueryCompleteParams eventParams = new QueryCompleteParams { OwnerUri = ownerUri, BatchSummaries = q.BatchSummaries }; await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams); }; query.QueryCompleted += completeCallback; query.QueryFailed += failureCallback; // Add the callbacks that were provided by the caller // If they're null, that's no problem query.QueryCompleted += querySuccessCallback; query.QueryFailed += queryFailureCallback; // Setup the batch callbacks Batch.BatchAsyncEventHandler batchStartCallback = async b => { BatchEventParams eventParams = new BatchEventParams { BatchSummary = b.Summary, OwnerUri = ownerUri }; await eventSender.SendEvent(BatchStartEvent.Type, eventParams); }; query.BatchStarted += batchStartCallback; Batch.BatchAsyncEventHandler batchCompleteCallback = async b => { BatchEventParams eventParams = new BatchEventParams { BatchSummary = b.Summary, OwnerUri = ownerUri }; await eventSender.SendEvent(BatchCompleteEvent.Type, eventParams); }; query.BatchCompleted += batchCompleteCallback; Batch.BatchAsyncMessageHandler batchMessageCallback = async m => { MessageParams eventParams = new MessageParams { Message = m, OwnerUri = ownerUri }; await eventSender.SendEvent(MessageEvent.Type, eventParams); }; query.BatchMessageSent += batchMessageCallback; // Setup the ResultSet completion callback ResultSet.ResultSetAsyncEventHandler resultCallback = async r => { ResultSetEventParams eventParams = new ResultSetEventParams { ResultSetSummary = r.Summary, OwnerUri = ownerUri }; await eventSender.SendEvent(ResultSetCompleteEvent.Type, eventParams); }; query.ResultSetCompleted += resultCallback; // Launch this as an asynchronous task query.Execute(); }
private static void ExecuteAndCompleteQuery(string ownerUri, Query query, IEventSender eventSender, Query.QueryAsyncEventHandler querySuccessCallback, Query.QueryAsyncErrorEventHandler queryFailureCallback) { // Setup the callback to send the complete event Query.QueryAsyncEventHandler completeCallback = async q => { // Send back the results QueryCompleteParams eventParams = new QueryCompleteParams { OwnerUri = ownerUri, BatchSummaries = q.BatchSummaries }; Logger.Write(TraceEventType.Information, $"Query:'{ownerUri}' completed"); await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams); }; // Setup the callback to send the failure event Query.QueryAsyncErrorEventHandler failureCallback = async(q, e) => { // Send back the results QueryCompleteParams eventParams = new QueryCompleteParams { OwnerUri = ownerUri, BatchSummaries = q.BatchSummaries }; Logger.Write(TraceEventType.Error, $"Query:'{ownerUri}' failed"); await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams); }; query.QueryCompleted += completeCallback; query.QueryFailed += failureCallback; // Add the callbacks that were provided by the caller // If they're null, that's no problem query.QueryCompleted += querySuccessCallback; query.QueryFailed += queryFailureCallback; // Setup the batch callbacks Batch.BatchAsyncEventHandler batchStartCallback = async b => { BatchEventParams eventParams = new BatchEventParams { BatchSummary = b.Summary, OwnerUri = ownerUri }; Logger.Write(TraceEventType.Information, $"Batch:'{b.Summary}' on Query:'{ownerUri}' started"); await eventSender.SendEvent(BatchStartEvent.Type, eventParams); }; query.BatchStarted += batchStartCallback; Batch.BatchAsyncEventHandler batchCompleteCallback = async b => { BatchEventParams eventParams = new BatchEventParams { BatchSummary = b.Summary, OwnerUri = ownerUri }; Logger.Write(TraceEventType.Information, $"Batch:'{b.Summary}' on Query:'{ownerUri}' completed"); await eventSender.SendEvent(BatchCompleteEvent.Type, eventParams); }; query.BatchCompleted += batchCompleteCallback; Batch.BatchAsyncMessageHandler batchMessageCallback = async m => { MessageParams eventParams = new MessageParams { Message = m, OwnerUri = ownerUri }; Logger.Write(TraceEventType.Information, $"Message generated on Query:'{ownerUri}' :'{m}'"); await eventSender.SendEvent(MessageEvent.Type, eventParams); }; query.BatchMessageSent += batchMessageCallback; // Setup the ResultSet available callback ResultSet.ResultSetAsyncEventHandler resultAvailableCallback = async r => { ResultSetAvailableEventParams eventParams = new ResultSetAvailableEventParams { ResultSetSummary = r.Summary, OwnerUri = ownerUri }; Logger.Write(TraceEventType.Information, $"Result:'{r.Summary} on Query:'{ownerUri}' is available"); await eventSender.SendEvent(ResultSetAvailableEvent.Type, eventParams); }; query.ResultSetAvailable += resultAvailableCallback; // Setup the ResultSet updated callback ResultSet.ResultSetAsyncEventHandler resultUpdatedCallback = async r => { ResultSetUpdatedEventParams eventParams = new ResultSetUpdatedEventParams { ResultSetSummary = r.Summary, OwnerUri = ownerUri }; Logger.Write(TraceEventType.Information, $"Result:'{r.Summary} on Query:'{ownerUri}' is updated with additional rows"); await eventSender.SendEvent(ResultSetUpdatedEvent.Type, eventParams); }; query.ResultSetUpdated += resultUpdatedCallback; // Setup the ResultSet completion callback ResultSet.ResultSetAsyncEventHandler resultCompleteCallback = async r => { ResultSetCompleteEventParams eventParams = new ResultSetCompleteEventParams { ResultSetSummary = r.Summary, OwnerUri = ownerUri }; Logger.Write(TraceEventType.Information, $"Result:'{r.Summary} on Query:'{ownerUri}' is complete"); await eventSender.SendEvent(ResultSetCompleteEvent.Type, eventParams); }; query.ResultSetCompleted += resultCompleteCallback; // Launch this as an asynchronous task query.Execute(); }
private static async Task ExecuteAndCompleteQuery(QueryExecuteParams executeParams, RequestContext <QueryExecuteResult> requestContext, Query query) { // Skip processing if the query is null if (query == null) { return; } // Setup the query completion/failure callbacks Query.QueryAsyncEventHandler callback = async q => { // Send back the results QueryExecuteCompleteParams eventParams = new QueryExecuteCompleteParams { OwnerUri = executeParams.OwnerUri, BatchSummaries = q.BatchSummaries }; await requestContext.SendEvent(QueryExecuteCompleteEvent.Type, eventParams); }; Query.QueryAsyncErrorEventHandler errorCallback = async errorMessage => { // Send back the error message QueryExecuteCompleteParams eventParams = new QueryExecuteCompleteParams { OwnerUri = executeParams.OwnerUri, Message = errorMessage }; await requestContext.SendEvent(QueryExecuteCompleteEvent.Type, eventParams); }; query.QueryCompleted += callback; query.QueryFailed += callback; query.QueryConnectionException += errorCallback; // Setup the batch callbacks Batch.BatchAsyncEventHandler batchStartCallback = async b => { QueryExecuteBatchNotificationParams eventParams = new QueryExecuteBatchNotificationParams { BatchSummary = b.Summary, OwnerUri = executeParams.OwnerUri }; await requestContext.SendEvent(QueryExecuteBatchStartEvent.Type, eventParams); }; query.BatchStarted += batchStartCallback; Batch.BatchAsyncEventHandler batchCompleteCallback = async b => { QueryExecuteBatchNotificationParams eventParams = new QueryExecuteBatchNotificationParams { BatchSummary = b.Summary, OwnerUri = executeParams.OwnerUri }; await requestContext.SendEvent(QueryExecuteBatchCompleteEvent.Type, eventParams); }; query.BatchCompleted += batchCompleteCallback; // Setup the ResultSet completion callback ResultSet.ResultSetAsyncEventHandler resultCallback = async r => { QueryExecuteResultSetCompleteParams eventParams = new QueryExecuteResultSetCompleteParams { ResultSetSummary = r.Summary, OwnerUri = executeParams.OwnerUri }; await requestContext.SendEvent(QueryExecuteResultSetCompleteEvent.Type, eventParams); }; query.ResultSetCompleted += resultCallback; // Launch this as an asynchronous task query.Execute(); // Send back a result showing we were successful string messages = null; if (query.Batches.Length == 0) { // If there were no batches to execute, send back an informational message that the commands were completed successfully messages = SR.QueryServiceCompletedSuccessfully; } await requestContext.SendResult(new QueryExecuteResult { Messages = messages }); }
public void BatchExecuteNoResultSets() { // Setup: // ... Create a callback for batch start BatchSummary batchSummaryFromStart = null; Batch.BatchAsyncEventHandler batchStartCallback = b => { batchSummaryFromStart = b.Summary; return(Task.FromResult(0)); }; // ... Create a callback for batch completion BatchSummary batchSummaryFromCompletion = null; Batch.BatchAsyncEventHandler batchCompleteCallback = b => { batchSummaryFromCompletion = b.Summary; return(Task.FromResult(0)); }; // ... Create a callback for result completion bool resultCallbackFired = false; ResultSet.ResultSetAsyncEventHandler resultSetCallback = r => { resultCallbackFired = true; return(Task.FromResult(0)); }; // If I execute a query that should get no result sets var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory); batch.BatchStart += batchStartCallback; batch.BatchCompletion += batchCompleteCallback; batch.ResultSetCompletion += resultSetCallback; batch.Execute(GetConnection(Common.CreateTestConnectionInfo(null, false)), CancellationToken.None).Wait(); // Then: // ... It should have executed without error Assert.True(batch.HasExecuted, "The query should have been marked executed."); Assert.False(batch.HasError, "The batch should not have an error"); // ... The results should be empty Assert.Empty(batch.ResultSets); Assert.Empty(batch.ResultSummaries); // ... The results should not be null Assert.NotNull(batch.ResultSets); Assert.NotNull(batch.ResultSummaries); // ... There should be a message for how many rows were affected Assert.Equal(1, batch.ResultMessages.Count()); // ... The callback for batch start should have been called // ... The info from it should have been basic Assert.NotNull(batchSummaryFromStart); Assert.False(batchSummaryFromStart.HasError); Assert.Equal(Common.Ordinal, batchSummaryFromStart.Id); Assert.Equal(Common.SubsectionDocument, batchSummaryFromStart.Selection); Assert.True(DateTime.Parse(batchSummaryFromStart.ExecutionStart) > default(DateTime)); Assert.Null(batchSummaryFromStart.ResultSetSummaries); Assert.Null(batchSummaryFromStart.Messages); Assert.Null(batchSummaryFromStart.ExecutionElapsed); Assert.Null(batchSummaryFromStart.ExecutionEnd); // ... The callback for batch completion should have been fired // ... The summary should match the expected info Assert.NotNull(batchSummaryFromCompletion); Assert.False(batchSummaryFromCompletion.HasError); Assert.Equal(Common.Ordinal, batchSummaryFromCompletion.Id); Assert.Equal(0, batchSummaryFromCompletion.ResultSetSummaries.Length); Assert.Equal(1, batchSummaryFromCompletion.Messages.Length); Assert.Equal(Common.SubsectionDocument, batchSummaryFromCompletion.Selection); Assert.True(DateTime.Parse(batchSummaryFromCompletion.ExecutionStart) > default(DateTime)); Assert.True(DateTime.Parse(batchSummaryFromCompletion.ExecutionEnd) > default(DateTime)); Assert.NotNull(batchSummaryFromCompletion.ExecutionElapsed); // ... The callback for the result set should NOT have been fired Assert.False(resultCallbackFired); }
public void BatchExecuteTwoResultSets() { var dataset = new[] { Common.StandardTestData, Common.StandardTestData }; int resultSets = dataset.Length; ConnectionInfo ci = Common.CreateTestConnectionInfo(dataset, false); // Setup: Create a callback for batch completion BatchSummary batchSummaryFromCallback = null; Batch.BatchAsyncEventHandler batchCallback = b => { batchSummaryFromCallback = b.Summary; return(Task.FromResult(0)); }; // ... Create a callback for resultset completion int resultSummaryCount = 0; ResultSet.ResultSetAsyncEventHandler resultSetCallback = r => { resultSummaryCount++; return(Task.FromResult(0)); }; // If I execute a query that should get two result sets var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>()); Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory); batch.BatchCompletion += batchCallback; batch.ResultSetCompletion += resultSetCallback; batch.Execute(GetConnection(ci), CancellationToken.None).Wait(); // Then: // ... It should have executed without error Assert.True(batch.HasExecuted, "The batch should have been marked executed."); Assert.False(batch.HasError, "The batch should not have an error"); // ... There should be exactly two result sets Assert.Equal(resultSets, batch.ResultSets.Count()); foreach (ResultSet rs in batch.ResultSets) { // ... Each result set should have 5 rows Assert.Equal(Common.StandardRows, rs.RowCount); // ... Inside each result set should be 5 columns Assert.Equal(Common.StandardColumns, rs.Columns.Length); } // ... There should be exactly two result set summaries Assert.Equal(resultSets, batch.ResultSummaries.Length); foreach (ResultSetSummary rs in batch.ResultSummaries) { // ... Inside each result summary, there should be 5 rows Assert.Equal(Common.StandardRows, rs.RowCount); // ... Inside each result summary, there should be 5 column definitions Assert.Equal(Common.StandardColumns, rs.ColumnInfo.Length); } // ... The callback for batch completion should have been fired Assert.NotNull(batchSummaryFromCallback); // ... The callback for result set completion should have been fired Assert.Equal(2, resultSummaryCount); }
private static void ExecuteAndCompleteQuery(string ownerUri, IEventSender eventSender, Query query) { // Skip processing if the query is null if (query == null) { return; } // Setup the query completion/failure callbacks Query.QueryAsyncEventHandler callback = async q => { // Send back the results QueryCompleteParams eventParams = new QueryCompleteParams { OwnerUri = ownerUri, BatchSummaries = q.BatchSummaries }; await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams); }; query.QueryCompleted += callback; query.QueryFailed += callback; // Setup the batch callbacks Batch.BatchAsyncEventHandler batchStartCallback = async b => { BatchEventParams eventParams = new BatchEventParams { BatchSummary = b.Summary, OwnerUri = ownerUri }; await eventSender.SendEvent(BatchStartEvent.Type, eventParams); }; query.BatchStarted += batchStartCallback; Batch.BatchAsyncEventHandler batchCompleteCallback = async b => { BatchEventParams eventParams = new BatchEventParams { BatchSummary = b.Summary, OwnerUri = ownerUri }; await eventSender.SendEvent(BatchCompleteEvent.Type, eventParams); }; query.BatchCompleted += batchCompleteCallback; Batch.BatchAsyncMessageHandler batchMessageCallback = async m => { MessageParams eventParams = new MessageParams { Message = m, OwnerUri = ownerUri }; await eventSender.SendEvent(MessageEvent.Type, eventParams); }; query.BatchMessageSent += batchMessageCallback; // Setup the ResultSet completion callback ResultSet.ResultSetAsyncEventHandler resultCallback = async r => { ResultSetEventParams eventParams = new ResultSetEventParams { ResultSetSummary = r.Summary, OwnerUri = ownerUri }; await eventSender.SendEvent(ResultSetCompleteEvent.Type, eventParams); }; query.ResultSetCompleted += resultCallback; // Launch this as an asynchronous task query.Execute(); }