无限循环问题
Infinite while loop issues
我才刚刚开始使用 C# 编程,我 运行 正在处理后台线程的一个小问题 运行 在其中无限循环。
一点背景知识:我正在尝试为 Outlook 制作一个物理通知灯。现在我正在 WPF 应用程序中制作它,以便在将它放入 Outlook 加载项之前对其进行测试。
我有一个按钮可以打开一个新的后台线程并且 运行 是这个 class 的一个新实例:
public class LightControl
{
private byte light;
public byte Light
{
get { return light; }
set { light = value; }
}
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
private int delay;
public int Delay
{
get { return delay; }
set { delay = value; }
}
private bool status;
public bool Status
{
get { return status; }
set { status = value; }
}
public void notification()
{
Action<byte, string, int, bool> lightNot =
delegate(byte i, string c, int d, bool s)
{ lightLoop(i, c, d, s); };
lightNot(light, color, delay, status);
}
private void lightLoop(byte index, string color, int delay, bool state)
{
BlinkStick device = BlinkStick.FindFirst();
if (device != null && device.OpenDevice())
{
while (state)
{
device.SetColor(0, index, color);
Thread.Sleep(delay);
device.SetColor(0, index, "black");
Thread.Sleep(delay);
}
}
}
}
我有另一个按钮,它向这个 class 的状态成员提供一个 false,它应该滴入私有方法 lightLoop 并终止那个无限循环。杀死进程中的整个线程。
虽然它没有这样做。循环继续到 运行。可能是什么原因造成的?
如有任何帮助,我们将不胜感激。
以下是我开始讨论的方式:
private void lightStart(byte index)
{
Random random = new Random();
int randNumber = random.Next(0, 5);
LightControl light = new LightControl();
light.Light = index;
light.Color = colors[randNumber]; //random color generator just for fun.
light.Delay = 500;
light.Status = status; //global bool on the MainWindow Class
Thread lightThread = new Thread(new ThreadStart(light.notification));
lightThread.IsBackground = true;
lightThread.Start();
}
对于术语中的任何不准确之处,我仍然对所有这一切感到困惑,我提前道歉。
如@JohnKoerner 的评论所述,布尔值是值类型,因此如果您传递参数并在方法外部更改值,它将永远不会反映在方法内部。
为了解决它,将它封装在一个对象中并接收该对象作为参数。
参数
public class State
{
public Boolean IsActive {get;set;}
}
你的循环
while (state.IsActive)
{
//do the job
}
这样当你更新IsActive时属性方法就会知道。
另一种选择是使用 ref
来实现您想要的。本质上,它允许您传递对 bool
的引用,而不是评估时的实际值。这允许对值的更改影响它传递给的方法,即使它是值类型。
这是一个基本示例,您可以从中获取概念并将其应用于您的情况。
static bool state = true;
public static void _Main(string[] args)
{
Console.WriteLine("1. Main thread: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
Thread t = new Thread(new ThreadStart(StartLoop));
t.Start();
Console.WriteLine("2. Main thread: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
Thread.Sleep(5000);
state = false;
Console.WriteLine("3. Main thread: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
}
delegate void MyDelegate(ref bool s);
public static void StartLoop()
{
MyDelegate myDelegate = LoopMethod;
myDelegate(ref state);
}
public static void LoopMethod(ref bool state)
{
while (state)
{
Console.WriteLine("LoopMethod running: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
Thread.Sleep(1000);
}
}
输出:
1. Main thread: 20:00:28.3693277
2. Main thread: 20:00:28.3753284
LoopMethod running: 20:00:28.3793309
LoopMethod running: 20:00:29.3813856
LoopMethod running: 20:00:30.3816387
LoopMethod running: 20:00:31.3818790
LoopMethod running: 20:00:32.3829344
3. Main thread: 20:00:33.3760889
没有打印其他内容。
这还需要将您的 delegate
从匿名 delegate
更改为强类型 delegate
。
我才刚刚开始使用 C# 编程,我 运行 正在处理后台线程的一个小问题 运行 在其中无限循环。
一点背景知识:我正在尝试为 Outlook 制作一个物理通知灯。现在我正在 WPF 应用程序中制作它,以便在将它放入 Outlook 加载项之前对其进行测试。
我有一个按钮可以打开一个新的后台线程并且 运行 是这个 class 的一个新实例:
public class LightControl
{
private byte light;
public byte Light
{
get { return light; }
set { light = value; }
}
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
private int delay;
public int Delay
{
get { return delay; }
set { delay = value; }
}
private bool status;
public bool Status
{
get { return status; }
set { status = value; }
}
public void notification()
{
Action<byte, string, int, bool> lightNot =
delegate(byte i, string c, int d, bool s)
{ lightLoop(i, c, d, s); };
lightNot(light, color, delay, status);
}
private void lightLoop(byte index, string color, int delay, bool state)
{
BlinkStick device = BlinkStick.FindFirst();
if (device != null && device.OpenDevice())
{
while (state)
{
device.SetColor(0, index, color);
Thread.Sleep(delay);
device.SetColor(0, index, "black");
Thread.Sleep(delay);
}
}
}
}
我有另一个按钮,它向这个 class 的状态成员提供一个 false,它应该滴入私有方法 lightLoop 并终止那个无限循环。杀死进程中的整个线程。
虽然它没有这样做。循环继续到 运行。可能是什么原因造成的?
如有任何帮助,我们将不胜感激。
以下是我开始讨论的方式:
private void lightStart(byte index)
{
Random random = new Random();
int randNumber = random.Next(0, 5);
LightControl light = new LightControl();
light.Light = index;
light.Color = colors[randNumber]; //random color generator just for fun.
light.Delay = 500;
light.Status = status; //global bool on the MainWindow Class
Thread lightThread = new Thread(new ThreadStart(light.notification));
lightThread.IsBackground = true;
lightThread.Start();
}
对于术语中的任何不准确之处,我仍然对所有这一切感到困惑,我提前道歉。
如@JohnKoerner 的评论所述,布尔值是值类型,因此如果您传递参数并在方法外部更改值,它将永远不会反映在方法内部。
为了解决它,将它封装在一个对象中并接收该对象作为参数。
参数
public class State
{
public Boolean IsActive {get;set;}
}
你的循环
while (state.IsActive)
{
//do the job
}
这样当你更新IsActive时属性方法就会知道。
另一种选择是使用 ref
来实现您想要的。本质上,它允许您传递对 bool
的引用,而不是评估时的实际值。这允许对值的更改影响它传递给的方法,即使它是值类型。
这是一个基本示例,您可以从中获取概念并将其应用于您的情况。
static bool state = true;
public static void _Main(string[] args)
{
Console.WriteLine("1. Main thread: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
Thread t = new Thread(new ThreadStart(StartLoop));
t.Start();
Console.WriteLine("2. Main thread: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
Thread.Sleep(5000);
state = false;
Console.WriteLine("3. Main thread: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
}
delegate void MyDelegate(ref bool s);
public static void StartLoop()
{
MyDelegate myDelegate = LoopMethod;
myDelegate(ref state);
}
public static void LoopMethod(ref bool state)
{
while (state)
{
Console.WriteLine("LoopMethod running: {0}", DateTime.Now.ToString("HH:mm:ss.fffffff"));
Thread.Sleep(1000);
}
}
输出:
1. Main thread: 20:00:28.3693277
2. Main thread: 20:00:28.3753284
LoopMethod running: 20:00:28.3793309
LoopMethod running: 20:00:29.3813856
LoopMethod running: 20:00:30.3816387
LoopMethod running: 20:00:31.3818790
LoopMethod running: 20:00:32.3829344
3. Main thread: 20:00:33.3760889
没有打印其他内容。
这还需要将您的 delegate
从匿名 delegate
更改为强类型 delegate
。