简体   繁体   English

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

[英]How to wait for a method to finish on another thread?

I am new to multi-thread programming in C#. 我是C#中的多线程编程新手。 My problem is that I don't know how to wait for a method that is being run on another thread to finish, before it can continue to the next line. 我的问题是我不知道如何等待在另一个线程上运行的方法完成,然后才能继续下一行。 For example, something like this 例如这样的东西

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

Right now, it prints 0 on the console, which is not what I want (ie i = 100). 现在,它在控制台上打印0,这不是我想要的(即i = 100)。 What is the best way to do this? 做这个的最好方式是什么? BTW, I don't have access to the runThread that is created in class A 顺便说一句,我无权访问在class A创建的runThread

Thanks. 谢谢。

EDIT: 编辑:

It was a bit difficult to solve this problem without modifying a lot codes. 不修改批号就解决这个问题有点困难。 Therefore, we ended up with adding a condition in the public void Start() with which it can decide whether to run the RunLoop in a separate thread or not. 因此,我们最终在public void Start()添加了一个条件,通过该条件可以决定是否在单独的线程中运行RunLoop The condition was defined using an Enum field. 使用Enum字段定义条件。

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

And

public enum RunningMode { Asynchronous, Synchronous };

Thanks everyone for help. 谢谢大家的帮助。

The preferred method is to use the Task Parallel Library (TPL) and use Task with await . 首选方法是使用任务并行库 (TPL)并将Taskawait一起使用。

If you must use Threads, then use a ManualResetEvent or ManualResetEventSlim to signal the end of a method. 如果必须使用线程,请使用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();
    }
}

Your life would be so much better with tasks. 通过任务,您的生活会变得更好。

Your code could be this simple: 您的代码可能很简单:

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

Console.WriteLine(task.Result);

I like use Monitor.Wait() and Monitor.Pulse() in conjunction with "lock" operator. 我喜欢将Monitor.Wait()和Monitor.Pulse()与“锁定”运算符结合使用。 It works, but you must be careful, when you use this technique. 它可以工作,但是在使用此技术时必须小心。 I'm added some changes to your code to demonstrate it. 我在您的代码中添加了一些更改以进行演示。 Code below are prints i== 100, as you want. 下面的代码根据需要打印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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM