I have a Windows C# BackgroundService process that runs and executes some method. I'd like to run this method utilizing multi-threading on the system to process as much as possible. The DoWork
method contains a DB transaction and inside of that it performs some file I/O based on that transaction. I don't need the result of the tasks and only need to run them as quickly as possible.
Currently, I have it running with something like the below example. This works and I do see a performance improvement however this doesn't seem like the right way of doing this. I've also seen the ability to use Task.Run
and then WaitAll
but I saw similar performance as the Parallel.For
. What I'd like to do is constantly utilize the available threads to perform DoWork
. Am I doing this correctly, or is there a better way to do this?
Edit: Right now, everything is running synchronously except the initial call to DoWork
.
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service running.");
Parallel.For(0, 8, task => {
await DoWork(stoppingToken);
});
await Task.Delay(Timeout.Infinite, stoppingToken);
}
private async Task DoWork(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is working.");
using (var transactionScope = new TransactionScope())
{
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// get initial query which gets the row with data needed
// to perform the file I/O and build request
var query = "SELECT TOP(1) FROM MyTable" +
" WITH (readpast, rowlock, updlock)";
var row = connection.Query<MyType>(query);
// based on query, perform file i/o
var file = File.ReadAllText(row.FileName);
var data = JsonSerializer.Deserialize<MyData>(file);
var item = new MyObject() { Id = data.Id, Name = data.Name };
// call a WCF web service using item object, the web service
// has no asynchronous methods
service.SendRequest(item);
// update the transaction and then close
var updateQuery = "UPDATE MyTable SET Status = @Status WHERE Id = @Id";
connection.Execute<MyType>(updateQuery);
transactionScope.Complete();
}
}
catch(Exception ex)
{
// Log error
transactionScope.Dispose();
}
}
}