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();是因为我需要等到线程完成才能获得线程进程的结果。

但是上面的代码似乎不起作用,它只是冻结了,我不知道为什么!

所以我肯定做错了什么,你能告诉我该怎么做吗?

C#-使用一个函数;out”;线程中的参数

程序冻结的事实与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);
});