Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-使用带有“的函数”;“出去”;线程中的参数_C#_Multithreading_Function_Out Parameters - Fatal编程技术网

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以上版本时,这是一个完美的选择,非常感谢。