C#-使用带有“的函数”;“出去”;线程中的参数
我有以下函数,我想在C#-使用带有“的函数”;“出去”;线程中的参数,c#,multithreading,function,out-parameters,C#,Multithreading,Function,Out Parameters,我有以下函数,我想在系统中使用它。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; } 我尝试在(按钮单击)事件处理程序中
系统中使用它。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;
}
我尝试在(按钮单击)事件处理程序中使用以下代码:
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),但考虑到对NET 4.5的依赖性,您可以选择手动附加一个延续:
Task.Factory.StartNew(() => tempFunction(index, out Fullname, out Info))
.ContinueWith(r => MessageBox.Show(Fullname + "\n" + Info));
(为了使用任务
类,您需要以.NET 4.0为目标。)
如果您仅限于早期版本的框架,那么下一个最佳解决方案可能是使用BackgroundWorker
组件,因为您似乎正在使用Windows窗体应用程序 如果我正确理解了问题,那就是冻结。对我来说,问题在于线程的使用,而不是线程的使用。第二个将允许继续处理UI事件。这对您有用吗
Thread th = new Thread(() =>
{
tempfunction(index, out fullname, out info);
MessageBox.Show(fullname + ":" + info);
});
由于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);
}
首先消除容易出现的问题。你试过不用线程运行它吗?它完成了吗?这里还有一个问题:当你启动一个线程并立即加入它时,你可能已经调用了这个函数。这里没有异步执行任何操作。@ZanLynx没有线程,它可以完美地工作,但实际上我不知道如何在线程中使用这种函数。这个函数一点问题都没有,主要问题是线程。@ZanLynx好的,我应该做什么来等待线程完成,这样我才能得到结果?除了使用Join()
之外,我什么都不知道,我以前从未尝试过。@AlaaJoseph——这正是其他评论者所说的——如果你必须等待,那就没有意义了。如果你要使用.net 4.0,你仍然可以使用Async/wait,只需下载它。如果(看起来)OP使用的是ASP.net,这是否会导致相反的问题,即请求将完成并忘记另一个线程?Aaarghh!再次Join()。线程间通信、队列、消息、任务和soddin'Join()的所有其他可能方式(可能是最糟糕的选择)都是在“线程101”站点/页面上教授的第一种方法。德瑞克!这是一个简单易用的解决方案,非常感谢。当我的项目目标是框架的4.0以上版本时,这是一个完美的选择,非常感谢。