我是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 };
感谢大家的帮助。
答案 0 :(得分:2)
首选方法是使用Task Parallel Library(TPL)并将Task
与await
一起使用。
如果您必须使用主题,请使用ManualResetEvent
或ManualResetEventSlim
表示方法结束。
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();
}
}