在线程之间切换

时间:2015-05-19 15:31:45

标签: c# multithreading join

我有两个主题:

static Thread thread1 = new Thread(new ThreadStart(Team1Shots));
static Thread thread2 = new Thread(new ThreadStart(Team2Shots));

我希望thread1做一些工作(但不完整),然后thread2做一些工作(但不完整),然后回去完成thread1,然后回去完成thread2。

到目前为止,我有这个:

static void Main(string[] args)
{
    thread1.Start();
}

private static void Team1Shots()
{
   //Do Work in here...then

   thread2.Start();
   thread2.Join(); //Go to thread2

   //When join in thread2 to here
   //Do the rest of the work

   //Get thread2 to finish
}

private static void Team2Shots()
{
   //Do Work in here...
   thread1.Join(); //Go back to thread1

   //When thread1 finishes
   //Do the rest of the work

   // Finished All work
}

这不起作用,不知道从哪里开始。

2 个答案:

答案 0 :(得分:6)

由于你实际上并不想要并行完成任何工作,而只是让其中一个工作一次完成,你应该没有两个线程。有一个线程可以完成所有应该首先完成的事情,然后是所有应该完成的事情,然后是接下来应该完成的所有事情,依此类推。您通过创建启动/停止彼此进度的多个线程来不必要地创建工作。

答案 1 :(得分:1)

您可以使用BlockingCollection(T)在线程之间进行通信。将这些步骤建模为状态机,您可以在线程之间对消息进行乒乓。

static Thread thread1 = new Thread(new ThreadStart(Team1Shots));
static Thread thread2 = new Thread(new ThreadStart(Team2Shots));
static BlockingCollection<WorkerStateMessage> thread1Messages =
    new BlockingCollection<WorkerStateMessage>();
static BlockingCollection<WorkerStateMessage> thread2Messages =
    new BlockingCollection<WorkerStateMessage>();
static BlockingCollection<WorkerStateMessage> progressMessages =
    new BlockingCollection<WorkerStateMessage>();

static void Main(string[] args)
{
    thread1Messages.Add(new WorkerStateMessage { Type = MessageType.Work1, Data = 1 });
    thread1Messages.Add(new WorkerStateMessage { Type = MessageType.Work1, Data = 2 });
    thread1Messages.Add(new WorkerStateMessage { Type = MessageType.Work1, Data = 3 });
    thread1.Start();
    thread2.Start();
    // 4 step * 3 messages = 12 progress messages
    foreach(var message in progressMessages.GetConsumingEnumerable().Take(12))
    {
        Console.WriteLine(message.Progress);
        Console.WriteLine("Current data: {0}", message.Data);
    }

    thread1Messages.Add(WorkerStateMessage.Done);
    thread2Messages.Add(WorkerStateMessage.Done);
    thread1.Join();
    thread2.Join();
}

主要

private static void Team1Shots()
{
    foreach(var message in thread1Messages.GetConsumingEnumerable())
    {
        WorkerStateMessage nextMessage;
        switch(message.Type)
        {
            case MessageType.Work1:
                var added = message.Data + 1;
                nextMessage = new WorkerStateMessage
                {
                    Type = MessageType.Work2, 
                    Progress = "Add 1",
                    Data = added
                };
                progressMessages.Add(nextMessage);
                thread2Messages.Add(nextMessage);
            break;
            case MessageType.Work3:
                var multiplied = message.Data + 1;
                nextMessage = new WorkerStateMessage
                {
                    Type = MessageType.Work4,
                    Progress = "Multiply by 2",
                    Data = multiplied
                };
                progressMessages.Add(nextMessage);
                thread2Messages.Add(nextMessage);
            break;
            default:
                return;
        }
    }
}

线程1

private static void Team2Shots()
{
   foreach(var message in thread2Messages.GetConsumingEnumerable())
    {
        WorkerStateMessage nextMessage;
        switch(message.Type)
        {
            case MessageType.Work2:
                var added = message.Data + 2;
                nextMessage = new WorkerStateMessage
                {
                    Type = MessageType.Work3,
                    Progress = "Add 2",
                    Data = added
                };
                progressMessages.Add(nextMessage);
                thread1Messages.Add(nextMessage);
            break;
            case MessageType.Work4:
                var divided = message.Data / 2;
                nextMessage = new WorkerStateMessage 
                {
                    Type = MessageType.Work3,
                    Progress = "Divide by 2",
                    Data = divided
                };
                progressMessages.Add(nextMessage);
                thread2Messages.Add(nextMessage);
            break;
            default:
                return;
        }
    }
}

线程2

Add 1
Current data: 2
Add 1
Current data: 3
Add 1
Current data: 4
Add 2
Current data: 4
Add 2
Current data: 5
Add 2
Current data: 6
Multiply by 2
Current data: 5
Multiply by 2
Current data: 6
Multiply by 2
Current data: 7
Divide by 2
Current data: 2
Divide by 2
Current data: 3
Divide by 2
Current data: 3

输出

example.get