C# 多线程,带监视器进入/退出、等待/脉冲、锁定
我在办公室工作 我只能用班长课。没有信号/信号灯。(是的,这是为学校准备的,但不是家庭作业,只是为我的实践测试做一个免费的练习,我真的需要做好准备,所以让这个项目工作对我帮助很大) 我的问题是,我不知道要“锁定”哪些对象等(正如你所看到的,我已经尝试了很多,只是随机对象) 我有4个线程,1个经销商,3个吸烟者。我有一门商人课和一门吸烟者课。现在,我所有的吸烟者都去Monitor.Wait()那里,喝了一两杯烟,然后他们再也出不来了,即使每次经销商把烟放在桌子上,我都会打电话给Monitor.Pulsell()。我想这是因为我使用了错误的对象作为参数,我完全不知道 文本框和字符串主要用于在我的WPF类中给出数据 吸烟类:请原谅德语变量名。(烟草=烟草,纸张=纸张,施特雷赫=火焰,朱塔=烟熏,劳赫泽特=烟熏时间) 经销商类别:C# 多线程,带监视器进入/退出、等待/脉冲、锁定,c#,multithreading,monitor,C#,Multithreading,Monitor,我在办公室工作 我只能用班长课。没有信号/信号灯。(是的,这是为学校准备的,但不是家庭作业,只是为我的实践测试做一个免费的练习,我真的需要做好准备,所以让这个项目工作对我帮助很大) 我的问题是,我不知道要“锁定”哪些对象等(正如你所看到的,我已经尝试了很多,只是随机对象) 我有4个线程,1个经销商,3个吸烟者。我有一门商人课和一门吸烟者课。现在,我所有的吸烟者都去Monitor.Wait()那里,喝了一两杯烟,然后他们再也出不来了,即使每次经销商把烟放在桌子上,我都会打电话给Monitor.Pu
class Dealer
{
public static Random r = new Random();
public Boolean tabak = false;
public Boolean papier = false;
public Boolean streichhölzer = false;
public String zutaten;
public Boolean isEmpty()
{
return !(tabak || papier || streichhölzer);
}
public void setTabak()
{
tabak = true;
}
public void setPapier()
{
papier = true;
}
public void setStreichhölzer()
{
streichhölzer = true;
}
public void takeTabak()
{
tabak = false;
}
public void takePapier()
{
papier = false;
}
public void takeStreichhölzer()
{
streichhölzer = false;
}
TextBox status;
public Dealer(TextBox status)
{
this.status = status;
}
public static readonly object _locker = new object();
public void Go()
{
while (true)
{
if (isEmpty())
{
lock (this)
{
if (!tabak && !papier && !streichhölzer)
{
int zahl1 = r.Next(0, 3);
int zahl2 = r.Next(0, 3);
while (zahl1 == zahl2)
{
zahl2 = r.Next(0, 3);
}
switch (zahl1)
{
case (0):
setTabak();
break;
case (1):
setPapier();
break;
case (2):
setStreichhölzer();
break;
}
switch (zahl2)
{
case (0):
setTabak();
break;
case (1):
setPapier();
break;
case (2):
setStreichhölzer();
break;
}
updateText();
Monitor.PulseAll(this);
}
}
}
}
}
public void updateText()
{
try
{
status.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal
, new System.Windows.Threading.DispatcherOperationCallback(delegate
{
zutaten = "";
if (tabak)
{
zutaten += " Tabak ";
}
if (papier)
{
zutaten += " Papier ";
}
if (streichhölzer)
{
zutaten += " Streichhölzer ";
}
status.Text = zutaten;
status.UpdateLayout();
return null;
}), null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
有几件事不对:
它是否真的在方法名中使用德语Umlauts进行编译,比如“setstreichölzer”@elgonzo确实如此,尽管我发现标识符中的非ASCII字符由于不同的原因是不可取的。不过,C#有Unicode标识符,默认情况下,.cs文件是UTF8。非常感谢您的回复。我还在学习,现在我明白了锁定对象是如何工作的。我将尝试按照您在第4节中描述的那样现在就做。因为我的时间,当我找到更多的时间时,我会按照你在5中所描述的那样去做。将让您知道它是否有效,提前感谢:)
class Dealer
{
public static Random r = new Random();
public Boolean tabak = false;
public Boolean papier = false;
public Boolean streichhölzer = false;
public String zutaten;
public Boolean isEmpty()
{
return !(tabak || papier || streichhölzer);
}
public void setTabak()
{
tabak = true;
}
public void setPapier()
{
papier = true;
}
public void setStreichhölzer()
{
streichhölzer = true;
}
public void takeTabak()
{
tabak = false;
}
public void takePapier()
{
papier = false;
}
public void takeStreichhölzer()
{
streichhölzer = false;
}
TextBox status;
public Dealer(TextBox status)
{
this.status = status;
}
public static readonly object _locker = new object();
public void Go()
{
while (true)
{
if (isEmpty())
{
lock (this)
{
if (!tabak && !papier && !streichhölzer)
{
int zahl1 = r.Next(0, 3);
int zahl2 = r.Next(0, 3);
while (zahl1 == zahl2)
{
zahl2 = r.Next(0, 3);
}
switch (zahl1)
{
case (0):
setTabak();
break;
case (1):
setPapier();
break;
case (2):
setStreichhölzer();
break;
}
switch (zahl2)
{
case (0):
setTabak();
break;
case (1):
setPapier();
break;
case (2):
setStreichhölzer();
break;
}
updateText();
Monitor.PulseAll(this);
}
}
}
}
}
public void updateText()
{
try
{
status.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal
, new System.Windows.Threading.DispatcherOperationCallback(delegate
{
zutaten = "";
if (tabak)
{
zutaten += " Tabak ";
}
if (papier)
{
zutaten += " Papier ";
}
if (streichhölzer)
{
zutaten += " Streichhölzer ";
}
status.Text = zutaten;
status.UpdateLayout();
return null;
}), null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}