Answer the question
In order to leave comments, you need to log in
How to cook multithreading on tasks?
Good afternoon!
I want to figure out how to work with multithreading based on the Task class.
Unfortunately, on the Internet, almost all examples are either Task.Factory.StartNew or a bunch: the same tasks are shoved into an array and Task.WaitAll is done above it.
I'm interested in the situation when you need to read data from the database in a multi-threaded (not asynchronous) mode;
We create a model in which we place the result:
/// <summary>
/// Информация о разделах
/// </summary>
public class ImgStatisticDto
{
/// <summary>
/// Раздел
/// </summary>
public enImg Section { get; set; }
/// <summary>
/// Количество не готовых к использованию фото
/// </summary>
public int NotReady { get; set; }
/// <summary>
/// Общее количество фотографий в разделе
/// </summary>
public int Count { get; set; }
public ImgStatisticDto() { }
public ImgStatisticDto(enImg section)
{
Section = section;
}
}
private ImgStatisticDto GetStatistic(enImg section)
{
var res = new ImgStatisticDto(section);
using (var db = ImagesContextFactory.Create(section))
{
var count = db.Image.CountAsync();
var notReady = db.Image.Where(x => !x.IsReady).CountAsync();
Task.WaitAll(count, notReady);
res.Count = count.Result;
res.NotReady = notReady.Result;
}
return res;
}
public async Task<IList<ImgStatisticDto>> GetStatistic()
{
var res = new List<ImgStatisticDto>();
foreach(enImg section in Enum.GetValues(typeof(enImg)))
{
if (section == enImg.none) continue;
res.Add(GetStatistic(section));
}
return res;
}
Answer the question
In order to leave comments, you need to log in
You are wrong. You do not have parallel execution of tasks in the GetStatistic() method.
This is count.Result
equivalent to
This is a normal synchronous execution.
This is how Task.WaitAll(count, notReady);
you launched tasks in parallel, but you won’t get the result from them.
If you want to execute the loop body in different threads in a loop, use Parallel.ForEach
try wrapping the code inside the task like this, and then the DBMS will take care of multithreading and the order of requests:
public async Task<IList<ImgStatisticDto>> GetStatistic()
{
var res = new List<ImgStatisticDto>();
using (var transaction = context.Database.BeginTransaction())
{
try
{
foreach(enImg section in Enum.GetValues(typeof(enImg)))
{
if (section == enImg.none) continue;
res.Add(GetStatistic(section));
}
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
}
return res;
}
The mere use of Task does not imply multithreading.
Here is an example proving this. And this article will help you figure it out.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question