|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace _02_ThreadSincro {
|
|
|
|
|
public partial class Form1 : Form {
|
|
|
|
|
public Form1() {
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int[] numeros = new int[1000];
|
|
|
|
|
int iterador;
|
|
|
|
|
int numero;
|
|
|
|
|
private void Button1_Click(object sender, EventArgs e) {
|
|
|
|
|
iterador = 0;
|
|
|
|
|
numero = 0;
|
|
|
|
|
//crear
|
|
|
|
|
Thread t1 = new Thread(this.rellena);
|
|
|
|
|
Thread t2 = new Thread(this.rellena);
|
|
|
|
|
Thread t3 = new Thread(this.rellena);
|
|
|
|
|
Thread t4 = new Thread(this.rellena);
|
|
|
|
|
Thread t5 = new Thread(this.rellena);
|
|
|
|
|
|
|
|
|
|
//inicializar
|
|
|
|
|
t1.Start();
|
|
|
|
|
t2.Start();
|
|
|
|
|
t3.Start();
|
|
|
|
|
t4.Start();
|
|
|
|
|
t5.Start();
|
|
|
|
|
|
|
|
|
|
//esperar
|
|
|
|
|
t1.Join();
|
|
|
|
|
t2.Join();
|
|
|
|
|
t3.Join();
|
|
|
|
|
t4.Join();
|
|
|
|
|
t5.Join();
|
|
|
|
|
|
|
|
|
|
//ver resultado
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
|
Debug.WriteLine(numeros[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Object o = new object();
|
|
|
|
|
private void rellena() {
|
|
|
|
|
for (int i = 0; i < 200; i++) {
|
|
|
|
|
lock (o) {
|
|
|
|
|
numero++;
|
|
|
|
|
numeros[iterador] = numero;
|
|
|
|
|
Thread.Sleep(50);
|
|
|
|
|
iterador++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Button2_Click(object sender, EventArgs e) {
|
|
|
|
|
Thread t1 = new Thread(this.rellenaM);
|
|
|
|
|
Thread t2 = new Thread(this.leeM);
|
|
|
|
|
t1.Start();
|
|
|
|
|
t2.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool fin_bloqueo = false;
|
|
|
|
|
//método asociado al hilo productor
|
|
|
|
|
private void rellenaM() {
|
|
|
|
|
for (int i = 999; i >= 0; i--) {
|
|
|
|
|
numeros[i] = i;
|
|
|
|
|
//Thread.Sleep(5);
|
|
|
|
|
}
|
|
|
|
|
lock (this) {
|
|
|
|
|
fin_bloqueo = true;
|
|
|
|
|
Monitor.Pulse(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//método asociado al hilo consumidor
|
|
|
|
|
private void leeM() {
|
|
|
|
|
Thread.Sleep(500);
|
|
|
|
|
lock (this)
|
|
|
|
|
while (!fin_bloqueo)
|
|
|
|
|
Monitor.Wait(this);
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
|
Debug.WriteLine(numeros[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Button3_Click(object sender, EventArgs e) {
|
|
|
|
|
Thread t1 = new Thread(this.Ping);
|
|
|
|
|
Thread t2 = new Thread(this.Pong);
|
|
|
|
|
t1.Start();
|
|
|
|
|
t2.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object o1 = new object();
|
|
|
|
|
object o2 = new object();
|
|
|
|
|
|
|
|
|
|
private void Ping() {
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
|
lock (o2)
|
|
|
|
|
Monitor.Pulse(o2);
|
|
|
|
|
lock (o1) {
|
|
|
|
|
Monitor.Wait(o1);
|
|
|
|
|
Debug.WriteLine("ping");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Pong() {
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
|
lock (o1)
|
|
|
|
|
Monitor.Pulse(o1);
|
|
|
|
|
lock (o2) {
|
|
|
|
|
Monitor.Wait(o2);
|
|
|
|
|
Debug.WriteLine("PONG");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Button4_Click(object sender, EventArgs e) {
|
|
|
|
|
//creo
|
|
|
|
|
Thread t1 = new Thread(this.LongFor);
|
|
|
|
|
|
|
|
|
|
t1.Start();
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
Debug.WriteLine("Abortando thread t1");
|
|
|
|
|
if (t1.IsAlive) Debug.WriteLine("Hilo t1 vivo antes de abort");
|
|
|
|
|
t1.Abort();
|
|
|
|
|
if (t1.IsAlive) Debug.WriteLine("Hilo t1 vivo después de abort");
|
|
|
|
|
t1.Join();
|
|
|
|
|
Debug.WriteLine("Fin de prueba");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LongFor() {
|
|
|
|
|
try {
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
|
Debug.WriteLine(">>>Thread trabajando");
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (ThreadAbortException e) {
|
|
|
|
|
Debug.WriteLine(">>>Excepción capturada: "+ e.Message);
|
|
|
|
|
Thread.ResetAbort();
|
|
|
|
|
}
|
|
|
|
|
Debug.WriteLine(">>>Thread todavía vivo");
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
Debug.WriteLine(">>>Thread finalizando");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Button5_Click(object sender, EventArgs e) {
|
|
|
|
|
//de esta forma no funcionaría
|
|
|
|
|
//Thread t1 = new Thread(this.EscribeText1);
|
|
|
|
|
//t1.Start();
|
|
|
|
|
|
|
|
|
|
Thread t1 = new Thread(this.EscribeText2);
|
|
|
|
|
t1.Start();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void EscribeText1() {
|
|
|
|
|
this.textBox1.Text = "Hola";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delegate void DelegadoText();
|
|
|
|
|
|
|
|
|
|
delegate void DelegadoTextParametros(string s);
|
|
|
|
|
|
|
|
|
|
private void EscribeText2() {
|
|
|
|
|
//invocación delegado sin parámetros
|
|
|
|
|
DelegadoText dc1 = new DelegadoText(this.Escribir);
|
|
|
|
|
this.Invoke(dc1);
|
|
|
|
|
|
|
|
|
|
//invocación a un delgado con parámetros
|
|
|
|
|
DelegadoTextParametros dc2 = new DelegadoTextParametros(this.Escribir2);
|
|
|
|
|
this.Invoke(dc2, "hola con parámetros");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Escribir() {
|
|
|
|
|
this.textBox1.Text = "TEXTO";
|
|
|
|
|
}
|
|
|
|
|
private void Escribir2(string s) {
|
|
|
|
|
this.textBox2.Text = s;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|