如何立即杀死所有线程

时间:2017-12-01 21:44:59

标签: c# multithreading

我做了一个小例子程序,用两个线程计算数字。它还会在计数旁边打印第二个数字,这样我就可以看到哪个线程打印了哪个数字。

现在我的目标是让一个线程在其中一个计数为7时立即停止。我不知道如何去做。我想过将一个线程数组作为参数传递给Counter,然后使用foreach循环来中止两个线程。问题是t0可能正在执行它并调用t0.Abort(),因此t1.Abort()将不再被调用。

public static int count = 0;
private static object lockObject = new object();

static void Main(string[] args) {
    Thread t0 = new Thread(() => Counter(1, 10));
    Thread t1 = new Thread(() => Counter(10, 20));

    t0.Start();
    t1.Start();

    t0.Join();
    t1.Join();

    Console.ReadLine();
}

public static void Counter(int k, int m) {
    for(int i = k; i < m; i++) {
        lock (lockObject) {
            count++;
            Console.WriteLine(count + " " + i);
            if (i == 7) {
                /* 
                 * Code that will kill thread t0 and t1
                 */
            }
        }
    }
}

输出应该是

1 1
2 2
3 10
4 11
5 12
6 13
7 14

是否有人建议如何杀死t0t1

3 个答案:

答案 0 :(得分:3)

使用标志,在本例中为“run”。

public static int count = 0;
private static object lockObject = new object();
static bool run = true;

static void Main(string[] args) {
    Thread t0 = new Thread(() => Counter(1, 10));
    Thread t1 = new Thread(() => Counter(10, 20));        

    t0.Start();
    t1.Start();

    t0.Join();
    t1.Join();

    Console.ReadLine();
}

public static void Counter(int k, int m) {
    for(int i = k; i < m && run; i++) {
        lock (lockObject) {
            count++;
            Console.WriteLine(count + " " + i);
            if (i == 7) {
                run = false;
            }
        }
    }
}

答案 1 :(得分:2)

看看ManualResetEvent。你应该创建一个并且在Counter-method的for循环中你应该检查是否设置了事件,如果是,则打破for循环并返回。如果达到7,只需设置事件即可。该事件是线程安全的。

顺便说一下,好像是大学的家庭作业;)下次,亲自试试。

public static int count = 0;
private static object lockObject = new object();
private ManualResetEvent finish = new ManualResetEvent(false);

static void Main(string[] args) {
    Thread t0 = new Thread(() => Counter(1, 10));
    Thread t1 = new Thread(() => Counter(10, 20));

    t0.Start();
    t1.Start();

    t0.Join();
    t1.Join();

    Console.ReadLine();
}

public static void Counter(int k, int m) {
    for(int i = k; i < m; i++) {

        lock (lockObject) {
            if (finish.waitOne(0))
                break;

            count++;
            Console.WriteLine(count + " " + i);
            if (i == 7)
                finish.set()
        }
    }
}

答案 2 :(得分:0)

MSDN不知道什么是ManualResetEvent.isset(),但Matthias的答案看起来是正确的。如果将isset()替换为WaitOne(0),则代码可以正常工作。

private static int count = 0;
private static ManualResetEvent finish = new ManualResetEvent(false);
private static int stopValue = 7;
private static int syncInterval = 0; //0ms
private static object lockObject = new object();
static void Main(string[] args)
{
    Thread t0 = new Thread(() => Counter(1, 10));
    Thread t1 = new Thread(() => Counter(10, 20));
    t0.Name = "Thread 1";
    t1.Name = "Thread 2";

    t0.Start();
    t1.Start();

    t0.Join();
    t1.Join();

    Console.ReadKey();
}
public static void Counter(int k, int m)
{
    for (int i = k; i < m; i++)
    {
        lock (lockObject)
        {
            if (finish.WaitOne(syncInterval))
                break;
            count++;
            Console.WriteLine($"{count} {i}");
            if (count == stopValue)
            {
                finish.Set();
            }
        }
    }
}