如果我有课
public Class foo
{
public foo()
{
myclass = new myclass(param)
myclass.initiateState();
val = myclass.getValues();
}
}
Class.initiateState()
是一个漫长的过程,它在我的GUI构造函数中运行,我想开始用一个线程运行,但是下一行转到同一个类来获取一些数据,但是如果我运行第一个在一个新线程中行,然后在它完成之前执行。
我该如何解决这个问题?
答案 0 :(得分:11)
制作BackgroundWorker
。
在DoWork
事件方法内,添加myClass.initiateState()
电话。在RunWorkerCompleted
事件方法内,请致电myClass.getValues();
这将导致initiateState
在后台线程上运行,完成后将在GUI线程上触发getValues
。
另外,请注意在C#中,与Java相比,使用大写字母启动方法名称是正常的。因此,方法应具有名称InitiateState
和GetValues
:)
答案 1 :(得分:4)
最简单的方法是:
public Class foo
{
public foo()
{
myclass = new myclass(param)
new Action( () => myclass.initiateState() ).BeginInvoke(initiateStateFinished, null)
}
private void initiateStateFinished(IAsyncResult ar)
{
val = myclass.getValues();
//other actions
}
}
甚至更短
public foo()
{
myclass = new myclass(param)
new Action( () => myclass.initiateState() )
.BeginInvoke(_ => val = myclass.getValues(), null)
}
答案 2 :(得分:1)
所以,你想要执行BOTH
myclass.initiateState();
val = myclass.getValues();
在新线程中(val是返回值)?
您可以使用.NET 4.0 Tasks
轻松完成此操作:
var someBackgroundTask = new System.Threading.Tasks.Task<*return type of GetValue()*>(() =>
{
myclass.initiateState();
return myclass.getValue();
});
someBackgroundTask.Start();
然后使用someBackgroundTask.Result
来获得结果。你唯一的问题是你需要等待(或检查关键点)以查看Task
是否已经完成。您可以使用someBackgroundTask.IsCompleted
检查它是否仍然有效,或someBackgroundTask.Wait()
等待它完成。
答案 3 :(得分:0)
从给出的示例看来,整个foo
类应该在一个单独的线程中运行。为了适用于其他情况,我将假设foo
中还有其他内容不应该作为不同的线程运行。
首先在foo
中创建一个DoWork方法:
private void DoWork() {
myclass = new myclass(param);
myclass.initiateState();
val = myclass.getValues();
}
然后更改构造函数以将其作为线程运行:
public foo() {
Thread workerThread = new Thread(this.DoWork);
/* ... do other stuff ... */
}