【问题标题】:Changing Textbox.text within a method; For loop not looping due to Return在方法中更改 Textbox.text;由于 Return 导致 For 循环不循环
【发布时间】:2017-01-27 03:35:13
【问题描述】:

下面是一个按钮,按下它会调用一个 ping 一堆 IP 地址的函数。如果 IP 地址返回响应,它会将 IP 地址添加到 output_networkSearch.Text。

private void button_networkSearch_Click(object sender, RoutedEventArgs e)
    {
        output_networkSearch.Text = networkSearch(Convert.ToInt32(input_searchLimit.Text)); 

    }

以下不是整个方法,只是我无法工作的部分。 for 循环从用户默认网关 IP 地址的最后一位数字开始,并在用户输入的任何限制 (1 - 255) 处停止。

// i 等于默认网关 IP 的最后一位,如果是 192.168.0.1 则 i = 1。

for (int i = Convert.ToInt32(splitGatewayIP[3]); i <= searchLimit; i = i + 1)
                    {
                        // If the method receieves a ping reply...
                        if (PingHostSweep(gatewayIPRebuild + i))
                        {
                            // Returns 192.168.0. + i + ACTIVE
                            string response = gatewayIPRebuild + i + " ACTIVE";

                            return response;
                        }
                        else
                        {
                            string response = gatewayIPRebuild + i + " CLOSED";

                            return response;

                        }
                    }

这在控制台应用程序上有效,但对于 WPF 应用程序,它似乎运行一次循环并由于 return 语句而停止。

解决此问题的想法是删除 Return Response 语句并尝试直接访问 TextBox (output_networkSearch)。

所以我会这样做:

for (int i = Convert.ToInt32(splitGatewayIP[3]); i <= searchLimit; i = i + 1)
                    {
                        // If the method receieves a ping reply...
                        if (PingHostSweep(gatewayIPRebuild + i))
                        {
                            // Returns 192.168.0. + i + ACTIVE
                            string response = gatewayIPRebuild + i + " ACTIVE";

                            output_networkSearch.Text = reponse;
                        }
                        else
                        {
                            string response = gatewayIPRebuild + i + " CLOSED";

                           output_networkSearch.Text = reponse;

                        }
                    }

但是,由于某种原因,我无法访问该方法中的文本框。我才刚刚开始学习 C#,所以我并不完全熟悉它的工作原理。

这是一个部分工作概念的图像。如您所见,限制设置为 10,因此它应该 ping IP 地址 1 到 10 并给出 ACTIVE 或 CLOSED 响应。这在我的控制台应用程序版本中确实有效。

WPF version

Console version

【问题讨论】:

  • 我将修改该方法,以便将成功的 IP 地址附加到字符串中,而不是“返回响应”。然后在 for 循环结束时,返回字符串。然后您可以照常使用该字符串更新文本框。这样做的缺点是文本框仅在所有 IP 地址都被 ping 通后才会更新,而不是持续更新。

标签: c# wpf methods textblock


【解决方案1】:

这可能对你有用

List<string> responses = new List<string>();
string response;
for (int i = Convert.ToInt32(splitGatewayIP[3]); i <= searchLimit; i = i + 1)
{
    if (PingHostSweep(gatewayIPRebuild + i))
    {
        response = gatewayIPRebuild + i + " ACTIVE";
    }
    else
    {
        response = gatewayIPRebuild + i + " CLOSED";
    }
    responses.Add(response)
}

现在,在循环之后,responses 列表将包含所有活动和关闭的 IP 的列表。就像您在控制台应用程序中所做的那样。

【讨论】:

  • 是的!这行得通。唯一的缺点是它首先检查所有 IP,然后更新文本框。因此,如果有几个 IP 需要检查,则需要一段时间。我以 return string.Join("\n", responses.ToArray()); 结束它以返回一个列表。 i.imgur.com/yD0I6Uz.jpg
【解决方案2】:

我认为你需要使用threading,后端需要许多子线程工作来扫描,当他们完成工作后将结果响应到MainForm,所以我写了一些代码希望可以帮助你!

using System.Threading;
using System.Threading.Tasks;


        public void Start(string ip)
        {
            Task.Factory.StartNew(() =>
           {
                // If the method receieves a ping reply...
                string response;
               if (PingHostSweep(ip))
               {
                    // Returns 192.168.0. + i + ACTIVE
                    response = ip + " ACTIVE";
               }
               else
               {
                   response = ip + " CLOSED";
               }
               this.Invoke((MethodInvoker)(() => { textBox1.AppendText("\r\n" + response); }));

           });
        }


        private void button1_Click(object sender, EventArgs e)
        {

            for (int i = 1; i <= 255; i++)
            {
                Start(String.Format("192.168.100.{0}", i));
            }
        }

【讨论】:

    【解决方案3】:

    前面的答案是正确的(尽管它没有涉及到你最终需要学习的更高级的点......委托和调用......长篇大论......现在不会让你厌烦)。

    你写的内容提炼到这一点:

    // 旁注:您实际上不能将 IPv4 地址视为四个“纯”四边形(但这不是您的问题)

    var notNecessarilyAHost = splitGatewayIP[3];
    var searchStart = Convert.ToInt32(notNecessarilyAHost);
    for (var i = searchStart; i <= searchLimit; ++i)
    {
        if (PingHostSweep(gatewayIPRebuild + i))
        {
            return $"{gatewayIPRebuild}{i} ACTIVE";
        }
        else
        {
            return $"{gatewayIPRebuild}{i} CLOSED";
        }
    }
    

    ...如果您(在心理上)逐步完成您编写的内容,那么很容易看到循环只会循环一次。进入循环后,我将等于 searchStart 是什么。然后你进入 if 测试。如果该测试为真,那么您将落入分支的真实一侧(即“...ACTIVE”)。否则,您将进入 else 分支(即“...CLOSED”。从那里...

    你总是回来。这将退出循环(以及包含它的函数)。您将永远不会再循环循环。 "break" 和 "return" (并且很可能 goto ...但那是另一天)将始终退出当前范围(范围是由 '{' 和 '}' 包装的代码块(无论是显式还是隐式编写)。

    关注?

    前面的答案是正确的。它会调整您的代码,以便循环将您在每次迭代中编写的字符串添加到字符串列表中。然后,当您退出循环时(因为我达到了 searchLimit),字符串列表将包含 N 很多,嗯,字符串。您可能想返回或继续工作。

    说了这么多,你不能(从技术上讲你可以,但你不应该)在 UI 线程中做任何事情。如果这样做,UI 将在循环运行(以及它运行的网络调用)时阻塞(并 100% 对用户无响应),等等。

    【讨论】:

    • 这就是我注意到的,它在执行循环时锁定。这一切都只是在玩,因为我最近才刚刚拿起 C#。但是感谢您的回复,因为这显然是我以后需要意识到和学习的东西。
    • 我的想法是更新文本,但我不知道为什么我无法访问我的方法中的文本块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2020-01-22
    • 1970-01-01
    相关资源
    最近更新 更多