我正在尝试在线程完成运行后运行一个函数。当按下UI按钮并且线程需要一段时间才能完成时,我的线程开始 一旦完成运行,我想调用一个函数。这是我到目前为止尝试的代码。当我尝试运行我的代码时,线程永远不会执行,应用程序冻结。关于如何解决这个问题的任何建议都会有所帮助。
public bool StartProbe()
{
if (File.Exists(Path.Combine(ObsProbeFolder, "probePJM.exe")))
{
ThreadStart ProbeThreadStart = new ThreadStart(() =>
// right side of lambda
{
// does stuff
});
ProbeThread = new Thread(ProbeThreadStart);
ProbeThread.Priority = ThreadPriority.BelowNormal;
ProbeThread.SetApartmentState(ApartmentState.STA);
ProbeThread.Start();
}
else
{
return false;
}
// waiting for thread to finish
ProbeThread.Join();
// run a function
loadData();
return true;
}
答案 0 :(得分:0)
我会使用BackgroundWorker:
Worker = new BackgroundWorker();
Worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
Worker.DoWork += Worker_DoWork;
Worker.RunWorkerAsync(new BackgroundArguments()
{
// arguments
});
在备用线程上工作:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// do stuff
}
返回UI线程:
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// load data or whatever on UI thread
}
答案 1 :(得分:0)
不要使用BackgroundWorker
- 这是一个非常古老的课程,我希望有一天它会被MS称为过时的课程。
正如你所说,你有一个按钮,为即发即弃场景创建一个async void
事件处理程序。当您检查一些exe
文件时,我假设您正在运行一些Process
in background。此外,您不需要一个线程来运行您的流程 - 您正在加入它,这就是UI挂起的原因。
private async void button_Click(object sender, EventArgs e)
{
// wait for a result from outer process
var result = await RunProcessInBackGround();
//do whatever you need in the UI-context
loadData(result);
}
// T is a type of the result, should be changed
private async Task<T> RunProcessInBackGround()
{
var tcs = new TaskCompletionSource<T>();
// run your process
var process new Process {/* your params here */};
process.Exited += (sender, args) =>
{
// here your process has already done his job
tcs.SetResult(result);
process.Dispose();
};
// process will start as a separate process, no need to create a thread to wait for it
process.Start();
// return the task which will be awaited for
return tcs.Task;
}