1

Изучаю работу с потоками в c#. Сделал небольшой пример на WinForms для себя.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;

namespace threadsLessons { public partial class Form1 : Form { public Form1() { InitializeComponent(); }

    private void button1_Click_1(object sender, EventArgs e)
    {
        Thread t1 = new Thread(() =>
        {
            M(label1);
        });
        t1.Start();

        new Thread(() => 
        {
            M(label2);
        }).Start();

        new Thread(() =>
        {
            M(label3);
        }).Start();

        new Thread(() =>
        {
            M(label4);
        }).Start();

        new Thread(() =>
        {
            M(label5);
        }).Start();

        new Thread(() =>
        {
            M(label6);
        }).Start();

    }

    void M(Label label)
    {
        SemaphoreSlim s = new SemaphoreSlim(1);

        s.Wait();
        for (int i = 0; i < 10; i++)
        {
           label.Text = i.ToString();
           Task.Delay(1000).Wait();
        }
        s.Release();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

}

}

Мое непонимание заключается в том, что обновляются сразу 6 label'ов. Хотя вроде как принимается только 1 поток одновременно. Вроде сам по себе Semaphore работает, но работает почему то больше потоков. Может я что то сделал не так или неправильно понимаю работу семафора?

aepot
  • 49,560

1 Answers1

5

Просто приведу этот код к рабочему виду. Проблема не в семафоре, а в том как вы код написали с ошибками. Семафор должен быть один на все задачи. Разные семафоры никак не зависят друг от друга, здесь нет никакой магии.

Чтобы не мудрить с потоками, использую async/await.

private async void button1_Click_1(object sender, EventArgs e)
{
    try
    {
        using SemaphoreSlim semaphore = new SemaphoreSlim(1);
        Label[] labels = new[] { label1, label2, label3, label4, label5, label6 };
        List<Task> tasks = new List<Task>();
    foreach (Label label in labels)
    {
        tasks.Add(() =&gt; M(label, semaphore));
    }

    await Task.WhenAll(tasks);
    MessageBox.Show(&quot;Готово&quot;);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

}

async Task M(Label label, Semaphore semaphore) { await semaphore.WaitAsync(); try { for (int i = 0; i < 10; i++) { label.Text = i.ToString(); await Task.Delay(1000); } } finally { semaphore.Release(); } }

Почитать еще:

aepot
  • 49,560