Asynchroniczność pomoc w rozumieniu

0

Cześć w zgłębiam się temat asynchroniczności w C#. Chciałbym się spytać czy tak się da oraz czy można napisać aplikację konsolową która

jest pętla for oraz dwa stringi a,b
i chciałbym aby string a wyswietlał się cały czas a string b z opóźnieniem 3 sekund jak mogę to zrobić z góry dziękuje za odpowiedź oraz rady :)

string a = "Ola";
string b = "Jan";

for(init i =0; i<10; i++) 
{
Console.Writeline(a);
Console.Writline(b);
}
0
Michał Warmuz napisał(a):

Cześć w zgłębiam się temat asynchroniczności w C#. Chciałbym się spytać czy tak się da oraz czy można napisać aplikację konsolową która

jest pętla for oraz dwa stringi a,b
i chciałbym aby string a wyswietlał się cały czas a string b z opóźnieniem 3 sekund jak mogę to zrobić z góry dziękuje za odpowiedź oraz rady :)

string a = "Ola";
string b = "Jan";

for(init i =0; i<10; i++) 
{
Console.Writeline(a);
Console.Writline(b);
}

@obscurity: Znaczy w cały czas póki pętla się wykonuje. Ja wiem że w tym przypadku jeżeli > Console.Writline(b); ma się wykonywać co 3 sekundy to nie zdąży ale chodzi o to aby > Console.Writline(a) wykonał się z każdą interacją pętli a > Console.Writline(b) co 3 sekundy póki wykonuje się pętla :)

0

napisałem coś takiego wydaję się że działa czy to jest dobry kod ? :)

        public static async Task ViewMessage()
        {
            await Task.Run(() => Console.WriteLine("Jan"));
        }

        public static async Task ViewMessage2()
        {
            await Task.Delay(3000);
            await Task.Run(() => Console.WriteLine("Ola"));
        }

        static async Task Main()
        {
            for (int i = 0; i < 5000; i++)
            {
                ViewMessage();
                ViewMessage2();
            }
        }
1

Ja bym do tego inaczej podszedł. W pętli uruchamiasz swoje taski przy kazdej iteracji. Ale pętla powinna raczej byc w tasku.

 static async Task Main(string[] args)
        {
            var tokenSource2 = new CancellationTokenSource();
            CancellationToken ct = tokenSource2.Token;

            Task task1 = Task.Run(async () =>
            {

                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("Jan");
                    await Task.Delay(500);
                }

                tokenSource2.Cancel();
            });

            Task task2 = Task.Run(async () =>
             {                 
                 while (!ct.IsCancellationRequested)
                 {
                     await Task.Delay(3000);
                     Console.WriteLine("Ola");                     
                 }
             }, tokenSource2.Token);

            

            await Task.WhenAll(task1, task2);


            Console.ReadKey();
        }   

Moje dwa taski lecą równolegle. Task2 wyswietla co trzy sekundy napis dopoki dziala task1

2
szydlak napisał(a):

Ja bym do tego inaczej podszedł. W pętli uruchamiasz swoje taski przy kazdej iteracji. Ale pętla powinna raczej byc w tasku.

Moje dwa taski lecą równolegle. Task2 wyswietla co trzy sekundy napis dopoki dziala task1

Thread.Sleep ma niewiele z asynchronicznością wspólnego. W ogóle ja bym nie używał nigdy Sleepa.

9

Pozwolę sobie napisać jeszcze jednego posta, bo mam większą chwilę żeby rozwinąć temat.

Początkujący programiści często mają problem ze zrozumieniem asynchroniczności, mylą ją z równolegleniem zadań. Jakiś czas temu jak sam się tego uczyłem wymyśliłem analogię z systemem obsługi w popularnej sieci restauracji. Kiedyś w McDonaldach na jedzenie czekało się synchronicznie, obecnie po wprowadzeniu systemu kolejkowania odbywa się to asynchronicznie. Na potrzeby wyjaśnienia nagnę trochę zasady.

Synchroniczność vs asynchroniczność vs równoległość

Synchroniczny nierównoległy McDonalds: Jest jeden kasjer, jeden kucharz.

  • zamawiamy burgera (czekamy przy kasie aż dostaniemy jedzenie),
  • kasjer przekazuje zamówienie do kucharza,
  • kucharz smaży burgera,
  • dostajemy zamówienie
var burger = CookMakeMeBurger();

Eat(burger);

Sychroniczny równoległy McDonalds: n kasjerów, n kucharzy

Tak samo jak w nierównoległym, tylko są na przykład 4 koljeki, których kasjerzy mogą odbierać zamówienia niezależnie. Co ważne w tym podejściu kasjer ma przypisanego swojego kucharza i nie może dać zamówienia innemu.

// never do this, do not use THREADS!
// for demonstration purposes only

var burgers = new Burger[3];
var burgerThreads = Enumerable
	.Range(0, 3)
	.Select(i => new Thread(
		() => burgers[i] = CookMakeMeBurger()))
	.ToArray();

foreach (var t in burgerThreads)
{
	t.Join();
}
			
foreach (var burger in burgers)
{
	Eat(burger);
}

Nigdy nie powinno się używać wątków wprost. Ktoś kiedyś w Microsofcie słusznie zauważył, że utworzenie i uruchomienie wątku jest kosztowne obliczeniowo i dlatego powinno się używać klasy Task, która korzysta z tzw. puli wątków.

Asynchroniczny nierównoległy McDonalds: n kasjerów, 1 kucharz

  • zamawiamy burgera,
  • dostajemy od kasjera numerek zamówienia,
  • możemy robić coś innego, np. iść do ubikacji,
  • kiedy skończymy robić [coś innego], a zamówienie jest już gotowe to odbieramy, jeśli nie jest to czekamy na burgera już synchronicznie.
var burgerTask = Task.Run(() =>
{
	return CookMakeMeBurger();
});

GotoToilet();

var burger = await burgerTask;

Eat(burger);

Asynchroniczny równoległy McDonalds: n kasjerów, n kucharzy

Podobnie jak w poprzednim przypadku, jednak mamy n kucharzy, czyli jakby kilka wątków. System kolejkowania zarządza, który kucharz dostanie które zamówienie.

var burgerTasks = Enumerable
	.Repeat(1, 3)
	.Select(_ => Task.Run(() => CookMakeMeBurger()))
	.ToArray();

GotoToilet();

var burgers = await Task.WhenAll(burgerTasks);

foreach (var burger in burgers)
{
	Eat(burger);
}

Zjeść burgery możemy również równolegle, ale ja już postanowiłem je zjeść po kolei.

4

Generalnie nie jestem fanem tutoriali ale mi w zrozumieniu asynchronicznosci mocno pomogly te 2 filmiki, szczególnie w kontekscie zrozumienia po co używa sie metyd asynchronicznych jesli np czekamy de facto synchronicznie na rezulatat z bazy danych:

1 użytkowników online, w tym zalogowanych: 0, gości: 1