Асинхронная задача C#, выполняемая в нескольких потоках без Task.Run?C#

Место общения программистов C#
Ответить
Anonymous
 Асинхронная задача C#, выполняемая в нескольких потоках без Task.Run?

Сообщение Anonymous »

Я протестировал следующий код:

Код: Выделить всё

using System;
using System.Threading;
using System.Threading.Tasks;

static class Program {
static TaskCompletionSource tsc;
static async Task F1(int i) {
// PART 1
await tsc.Task;
// PART 2
Console.WriteLine($"call: {i}, thread: {Thread.CurrentThread.GetHashCode()}");
}
static async Task Main() {
tsc = new();
var tasks = new Task[5];
for(int i = 0; i < tasks.Length; i++)
{
F1(i);
}
tsc.SetResult();
Console.WriteLine("what?!");
//await Task.Yield();
Console.WriteLine("done");
}
}
Насколько я понимаю, вызов «F1» (без «await») несколько раз произойдет в одном потоке («основном потоке»). Выполнение будет «ожидать» в «ЧАСТИ 1» («tsc.Task») и возвращаться для продолжения на вызывающем объекте, создавая 5 ожидающих задач. Для них я мог бы установить результат «TaskSourceCompletion», и мне потребовалось бы вызвать «Task.Yield», чтобы дать «время простоя» для выполнения всех задач, стоящих в очереди. Если бы я не выполнил команду «Yield», моя программа завершилась бы, не дав времени на завершение («ЧАСТЬ 2»).
Но текущий код выполняется следующим образом:

Код: Выделить всё

call: 0, thread: 1
call: 3, thread: 21
call: 1, thread: 17
call: 2, thread: 20
what?!
done
call: 4, thread: 19
Насколько я понимаю, если я хочу, чтобы код выполнялся в «ThreadPool» (или в других потоках), мне нужно было вызвать «Task.Run», иначе код будет поставлен в очередь в текущем потоке и выполняться только в «время простоя» (ожидая чего-то).
  • Но в настоящее время кажется, что все асинхронные задачи продолжают выполнение в разных потоках, в этом нет необходимости «Task.Run» для этого. Правильно ли это предположение?
  • Есть ли какой-либо способ заставить поведение, которое я ожидал, что все асинхронные задачи выполняются только в основном потоке, только если я дайте им «время простоя» (любое последующее ожидание, например: «Task.Yield» или «Task.Delay»).


Подробнее здесь: https://stackoverflow.com/questions/784 ... t-task-run
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»