vlákna
Vlákna
Jazyk C# podporuje paralelní spouštění kódu pomocí multithreadingu.
Můžeme spouštět několik částí kódu najednou a to každou část na samostatném vlákně.
Nejčastěji se vlákna používají v časově náročných operacích (složité výpočty, renderování) a při čekání na vstup od uživatele
(během zadávání může druhé vlákno zpracovávat zadávané data).
Vlákna potřebují jmenný prostor
System.Threading.
Základní konstrukce
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Vlakna
{
public partial class Zaklad : Form
{
public Zaklad()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread s = new Thread(vlakno); //Vytvoří nové vlákno
s.Start(); //a spustí ho.
}
private void vlakno()
{
while (true )
{
while (prepinac2)
{
this.BackColor = Color .Blue;//Přepne pozadí na sekundárním vlákně.
prepinac2 = false ;
}
}
}
private void button2_Click(object sender, EventArgs e)
{
this.BackColor = Color .Black;//Přepne pozadí na primarním vlákně.
}
private void button3_Click(object sender, EventArgs e)
{
prepinac2 = true ;
}
}
}
Dvojí volání a výpis do labelu
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Vlakna
{
public partial class vypis : Form
{
public vypis()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
new Thread(napis).Start(); //Zavolá napis() na novém vláknu.
napis(); //Zavolá napis() na primárním vláknu.
}
private void napis()
{
for (int i = 0; i < 5; i++)
{
label1.Invoke((MethodInvoker)delegate { label1.Text += i; }); //dovolí zapsat na primárním vláknu do labelu
}
}
}
}
Použití lock
Když jedno vlákno pracuje s proměnnou uzamkne ji.
Pokud chce ve stejnou chvíli použít stejnou proměnnou i jiné vlákno, chvíli počká, než mu uvolní místo předchozí vlákno.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Vlakna
{
public partial class sdileni : Form
{
private bool hlidac;
private int cislo;
private object zamek = new object();//zámek
public sdileni()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
hlidac = false;
new Thread(napis).Start();
napis();
}
private void napis()
{
lock (zamek) //Dovolí používat proměnné jen jednomu vláknu.
{
if (!hlidac)
{
cislo++;
label1.Invoke((MethodInvoker)delegate { label1.Text += cislo.ToString(); }); //Dovolí zapsat do labelu vytvořenému v jiném vlákně.
hlidac = true;
}
}
}
}
}