无限循环问题

时间:2015-06-12 23:01:33

标签: c# multithreading while-loop

我刚刚开始使用C#编程,我遇到了一个小问题,后台线程在其中运行无限循环。

一点背景:我正在尝试为Outlook制作物理通知灯。现在我在WPF应用程序中进行测试,然后在将它放入Outlook加载项之前对其进行测试。

我有一个按钮,可以打开一个新的后台线程并运行该类的新实例:

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);
            }


        }
    }

}

我有另一个按钮,它将一个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();


    }

我提前道歉,因为任何不准确的术语仍然围绕着这一切。

2 个答案:

答案 0 :(得分:2)

正如@ JohnKoerner的评论中所述,布尔值是值类型,因此如果传递参数并将值更改为方法之外的值,它将永远不会反映在其中。

要解决此问题,请将其封装在对象中并接收对象作为参数。

参数

public class State
{
    public Boolean IsActive {get;set;}
}

你的循环

while (state.IsActive)
{
    //do the job
}

这样,当您更新IsActive属性时,该方法将知道。

答案 1 :(得分:2)

另一种选择是使用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