如何等待方法在另一个线程上完成?

时间:2016-03-30 12:31:28

标签: c# multithreading

我是C#中多线程编程的新手。我的问题是我不知道如何等待另一个线程上运行的方法完成,然后才能继续下一行。例如,像这样的东西

public class A
{    
    int i;

    public A()
    {
        i = 0;
    }

    protected void RunLoop()
    {
        while(i < 100)
        {
            i++;
        }
    }

    public void Start()
    {
        TimerResolution.TimeBeginPeriod(1);
        runThread = new Thread(new ThreadStart(RunLoop));
        running = true;
        runThread.Start();
    }
}

public class B
{
    A classAInstance = new A();
    A.Start();
    Console.Writeline(i);
}

现在,它在控制台上打印0,这不是我想要的(即i = 100)。 做这个的最好方式是什么?顺便说一句,我无权访问 runThread

中创建的 class A

感谢。

编辑:

在不修改批次代码的情况下解决此问题有点困难。因此,我们最终在public void Start()中添加了一个条件,可以决定是否在单独的线程中运行RunLoop。条件是使用Enum字段定义的。

public void Start()
{
    TimerResolution.TimeBeginPeriod(1);
    running = true;
    if (runningMode == RunningMode.Asynchronous)
    {
        runThread = new Thread(new ThreadStart(RunLoop));
        runThread.Start();
    }
    else
    {
        RunLoop();
    }
}

public enum RunningMode { Asynchronous, Synchronous };

感谢大家的帮助。

3 个答案:

答案 0 :(得分:2)

首选方法是使用Task Parallel Library(TPL)并将Taskawait一起使用。

如果您必须使用主题,请使用ManualResetEventManualResetEventSlim表示方法结束。

void Main()
{
    var a = new A();
    a.Start();
    a.FinishedEvent.WaitOne();
    Console.WriteLine(a.Index);
}

// Define other methods and classes here
public class A
{
    ManualResetEvent mre = new ManualResetEvent(false);
    int i;

    public EventWaitHandle FinishedEvent
    {
        get { return mre; }
    }

    public int Index
    {
        get { return i; }
    }

    public A()
    {
        i = 0;
    }

    protected void RunLoop()
    {
        while (i < 1000)
        {
            i++;
        }
        mre.Set();
    }

    public void Start()
    {
        var runThread = new Thread(new ThreadStart(RunLoop));
        runThread.Start();
    }
}

答案 1 :(得分:2)

任务你的生活会好得多。

您的代码可能很简单:

var task = Task.Factory.StartNew(() =>
{
    var i = 0;
    while (i < 100)
    {
        i++;
    }
    return i;
});

Console.WriteLine(task.Result);

答案 2 :(得分:1)

我喜欢将Monitor.Wait()和Monitor.Pulse()与“lock”运算符结合使用。它有效,但是当你使用这种技术时你必须小心。 我在代码中添加了一些更改来演示它。下面的代码是打印i == 100,如你所愿。

public class A
{
    int i;

    public object SyncObject
    {  get; private set; }

    public A()
    {
        SyncObject = new object();
        i = 0;
    }

    protected void RunLoop()
    {
        while (i < 100)
        {
            i++;
        }

        lock (SyncObject)
        {
            Monitor.Pulse(SyncObject);
        }
    }

    public void Start()
    {
        var runThread = new Thread(new ThreadStart(RunLoop));
        runThread.Start();
    }

    public void PrintI()
    {
        Console.WriteLine("I == " + i);
    }
}

public class B
{
    public static void Run()
    {
        A classAInstance = new A();
        lock (classAInstance.SyncObject)
        {
            classAInstance.Start();
            Monitor.Wait(classAInstance.SyncObject);
        }
        classAInstance.PrintI();
    }
}