Hallo zusammen,
ich möchte folgende Aufgabenstellung lösen:
Simulation eins Konsumenten-Produzenten-Problem.
Es werden zwei Threads erzeugt, wobei der eine der Konsument und der andere der Produzent ist.
Die auszuführenden Methoden produzieren() und entnehmen() werden in der Klasse "Lager" definiert und parallel gestartet.
Es sollen Ausgaben beim Füllen / Entnehmen, sowie bei einem vollen und leeren Lager in einer grafischen Oberfläche (ListBox) erfolgen.
Umgesetzt habe ich das wie folgt:
1. Klasse Lager angelegt, sowie die Methoden entnehmen / produzieren ausprogrammiert.
2. Grafische Oberfläche erzeugt, Screenshot (1) siehe unten.
3. Mittels Delegate + Event versuche ich ListBox-Einträge hinzuzufügen. An dieser Stelle erhalte ich aber eine Exception. Den Fehler kann ich nicht erkennen. Die parallelen Ausgaben auf der Konsole dienen lediglich zur Kontrolle. Screenshot (2) siehe unten
Für jegliche Hilfen bin ich mehr als dankbar.
Eine ausführliche Erklärung wie der Fehler ensteht ist mir sehr wichtig. Ich möchte das Problem verstehen.
Hier mein Quelltext:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164:
| using System; using System.Windows.Forms; using System.Drawing; using System.Threading;
namespace GPI13_E_2 { class Lager : Form { int bestand = 500;
public delegate void addListBoxEntry(int wert); public event addListBoxEntry addEntry;
public void entnehmen() { int anz; Random anzahl = new Random();
while (true) { anz = anzahl.Next(0, 100);
if (bestand < anz) { Console.WriteLine("<-> Entnahme nicht möglich! Bestand: " + bestand + " versuchte Entnahme: " + anz); } else { lock (this) { bestand -= anz; } Console.WriteLine("<-- Verkaufe Ware. \tAnzahl entnommener Waren: " + anz + "\tNeuer Bestand: " + bestand); if (addEntry != null) { addEntry(anz); } } Thread.Sleep(2000); } }
public void produzieren() { int anz; Random anzahl = new Random();
while (true) { anz = anzahl.Next(0, 3000);
if ((bestand + anz) > 10000) { Console.WriteLine("<-> Einlagerung nicht möglich. Kapazität (10.000) wird überschritten!)"); } else { lock (this) { bestand += anz; } Console.WriteLine("--> Produziere Ware. \tAnzahl Wareneingang: " + anz + "\tNeuer Bestand: " + bestand); if (addEntry != null) { addEntry(anz); } } Thread.Sleep(3000); } } }
class Program { static ListBox output = new ListBox(); static Button go = new Button(); static Lager la = new Lager();
static void startConsumerProducer(object sender, EventArgs e) { if (go.Text == "GO!") { go.Text = "Stopp!";
Thread en = new Thread(new ThreadStart(la.entnehmen)); Thread pr = new Thread(new ThreadStart(la.produzieren)); en.Start(); pr.Start(); } else { go.Text = "GO!"; } }
static void add(int wert) { output.Items.Add(wert); }
static void Main(string[] args) {
Font fontInventory = new Font("Calibri", 30, FontStyle.Bold);
output.Name = "outputListBox"; output.Location = new Point(50, 150); output.Size = new Size(900, 400); output.BackColor = Color.LightGray;
Label inventory = new Label(); inventory.Name = "outputLabel"; inventory.Location = new Point(250, 25); inventory.Size = new Size(500, 100); inventory.BackColor = Color.LightGreen; inventory.Font = fontInventory; inventory.TextAlign = ContentAlignment.MiddleCenter; inventory.Text = "Aktueller Bestand:\n";
go.Name = "goButton"; go.Location = new Point(0, 0); go.Size = new Size(50, 50); go.Text = "GO!"; go.Click += new EventHandler(startConsumerProducer);
Button clear = new Button(); clear.Name = "clearButton"; clear.Location = new Point(50, 0); clear.Size = new Size(50, 50); clear.Text = "Clear"; la.DesktopLocation = new Point(0, 0); la.ClientSize = new Size(1000, 600); la.Text = "Lagerbestand";
la.Controls.Add(output); la.Controls.Add(inventory); la.Controls.Add(go); la.Controls.Add(clear); la.addEntry += new Lager.addListBoxEntry(add);
Application.Run(la); } } } |
Screenshot (1) - GUI
Screenshot (2) - Exception
Moderiert von
Narses: Bilder als Anhänge hochgeladen