C#-使用一个函数;out”;线程中的参数
本文关键字:out 线程 参数 函数 一个 C#- | 更新日期: 2023-09-27 18:27:22
我有以下函数,我想在System.Threading.Thread
:中使用它
private void tempFunction(int num, out string fullname, out string info)
{
// Doing a very long scenario.
// When finished, send results out!
fullname = result1;
info = result2;
}
我尝试在(button_Click)事件处理程序中使用以下代码:
private void submit_Button_Click(object sender, RoutedEventArgs e)
{
string Fullname = string.Empty, Info = string.Empty;
int index = 132;
Thread thread = new Thread(() => tempFunction(index, out Fullname, out Info));
thread.Start();
thread.Join();
// I always use "MessageBox" to check if what I want to do was done successfully
MessageBox.Show(Fullname + "'n" + Info);
}
您可以看到,我使用thread.Join();
是因为我需要等到线程完成才能获得线程进程的结果。
但是上面的代码似乎不起作用,它只是冻结了,我不知道为什么!
所以我肯定做错了什么,你能告诉我该怎么做吗?
程序冻结的事实与out
参数无关。
程序冻结是因为您调用Thread.Join()
,它基本上读作:"阻塞调用线程,直到我完成处理"。因为调用线程是UI线程,所以UI会冻结。
有很多方法可以解决这个问题,其中最吸引人的是使用await
关键字(C#5),但考虑到对NET4.5的依赖,您可以选择手动附加延续:
Task.Factory.StartNew(() => tempFunction(index, out Fullname, out Info))
.ContinueWith(r => MessageBox.Show(Fullname + "'n" + Info));
(您需要以.NET 4.0为目标才能使用Task
类。)
如果您仅限于早期版本的框架,那么下一个最佳解决方案可能是使用BackgroundWorker
组件,因为您看起来正在使用Windows窗体应用程序。
由于join语句,此代码将冻结UI,直到代码完成。此语句告诉当前线程,在本例中,当前线程是要阻止以完成工作线程的UI线程。加入完成后,将显示消息框。
使用已经建议的Task类或新的async/await构造。但是,如果您使用的是旧版本的框架,您可以使用以下
delegate void TempFunctionDelegate(int num, out string fullname, out string info);
private void tempFunction(int num, out string fullname, out string info)
{
/*do something for a long time*/
Thread.Sleep(5000);
fullname = "result1";
info = "result2";
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
string Fullname = string.Empty, Info = string.Empty;
int index = 132;
TempFunctionDelegate tempFunctionDelegate = tempFunction;
tempFunctionDelegate.BeginInvoke(index, out Fullname, out Info, CallBackToUI, tempFunctionDelegate);
}
void CallBackToUI(IAsyncResult ar)
{
var tempFunctionDelegate = ar.AsyncState as TempFunctionDelegate;
string fullName = null;
string info = null;
tempFunctionDelegate.EndInvoke(out fullName, out info, ar);
MessageBox.Show(fullName + "'n" + info);
}
如果我正确理解问题,那就是冻结。对我来说,问题是使用线程而不是BackgroundWorker。第二个将允许继续处理UI事件。
这对你有用吗?
Thread th = new Thread(() =>
{
tempfunction(index, out fullname, out info);
MessageBox.Show(fullname + ":" + info);
});