[C# windows窗体]在线程中调用listview时,其他控件不起作用

发布于 2024-09-14 13:03:19 字数 1255 浏览 4 评论 0原文

我是 C# 新手,我希望我对问题的描述是可读的。 这是我的问题,我正在为 win6.5 手机开发一个应用程序。该应用程序应该有一些菜单项,其中一个是“扫描”,单击时,它会重复扫描附近的 wifi 接入点,并将其显示在列表视图上。因此,我创建了一个带有 while 循环的线程,每 10 秒扫描一次,我还使用 listview.invoke 使 listview 在线程中可访问。单击“扫描”时,一切看起来都很好,但是,由于 while 循环线程的运行,无法单击其他菜单项。卡在这里好几天了,非常感谢大家的帮助~

private void menuItemScan_Click(object sender, EventArgs e)
        {
            ...

            Thread t = new Thread(new ThreadStart(ScanThread));
            t.Start();
        }

        private void ScanThread()
        {

            listView1.Invoke(new APScanCallback(APScan));

        }

        public void APScan() 
        {
            while (true)
            {

                listView1.Items.Clear();
                foreach (AccessPoint ap in wzcInterface.NearbyAccessPoints)
                {
                    ListViewItem item = new ListViewItem(ap.Name);
                    item.SubItems.Add(ap.PhysicalAddress.ToString());
                    item.SubItems.Add(ap.SignalStrength.Decibels.ToString());
                    item.SubItems.Add(ap.AuthenticationMode.ToString());
                    listView1.Items.Add(item);
                }
                listView1.Refresh();
                Thread.Sleep(10000);
            }

        }

I am new to C#, I hope my description of the problem is readable.
Here's my problem, I am developing a app for a win6.5 mobile. The App should have some memu items, one is 'scan', when clicked, it scans repeatedly the wifi access points nearby, and displays them on a listview. So i create a thread with a while loop for scanning every 10 seconds, i also use listview.invoke to make the listview accessible in the thread. Things looks fine when 'scan' is clicked, however, other menu items cannot be clicked due to the running of the while loop thread. I stuck here for several days, many thanks for u guys help~

private void menuItemScan_Click(object sender, EventArgs e)
        {
            ...

            Thread t = new Thread(new ThreadStart(ScanThread));
            t.Start();
        }

        private void ScanThread()
        {

            listView1.Invoke(new APScanCallback(APScan));

        }

        public void APScan() 
        {
            while (true)
            {

                listView1.Items.Clear();
                foreach (AccessPoint ap in wzcInterface.NearbyAccessPoints)
                {
                    ListViewItem item = new ListViewItem(ap.Name);
                    item.SubItems.Add(ap.PhysicalAddress.ToString());
                    item.SubItems.Add(ap.SignalStrength.Decibels.ToString());
                    item.SubItems.Add(ap.AuthenticationMode.ToString());
                    listView1.Items.Add(item);
                }
                listView1.Refresh();
                Thread.Sleep(10000);
            }

        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苹果你个爱泡泡 2024-09-21 13:03:19

Control.Invoke 将方法执行“排队”到处理 UI 的线程(以便将这些例程调用序列化到其他 UI 例程调用)。

即使您启动一个调用 Control.Invoke 的线程,例程 APSScan 也会在调用 Application.Run 的线程中执行...我看到 APSScan 永远不会返回,导致冻结 UI线。

解决方案是多次调用 Control.Invoke,在 ScanThread 例程中循环。

使用您的代码:

private void ScanThread()
    {

        while (true) {
            listView1.Invoke(new APScanCallback(APScan));
            Thread.Sleep(10000);
        }
    }

    public void APScan() 
    {
            listView1.Items.Clear();
            foreach (AccessPoint ap in wzcInterface.NearbyAccessPoints)
            {
                ListViewItem item = new ListViewItem(ap.Name);
                item.SubItems.Add(ap.PhysicalAddress.ToString());
                item.SubItems.Add(ap.SignalStrength.Decibels.ToString());
                item.SubItems.Add(ap.AuthenticationMode.ToString());
                listView1.Items.Add(item);
            }
            listView1.Refresh();
     }

Control.Invoke "enqueue" the method execution to the thread handling UI (in order to serialize those routine call to the other UI routine calls).

Even if you start a thread which calls Control.Invoke, the routine APSScan is executed in thread which has called Application.Run... and what I see is that APSScan never returns, causing to freeze the UI thread.

The solution is to call Control.Invoke multiple times, looping in ScanThread routine.

Using your code:

private void ScanThread()
    {

        while (true) {
            listView1.Invoke(new APScanCallback(APScan));
            Thread.Sleep(10000);
        }
    }

    public void APScan() 
    {
            listView1.Items.Clear();
            foreach (AccessPoint ap in wzcInterface.NearbyAccessPoints)
            {
                ListViewItem item = new ListViewItem(ap.Name);
                item.SubItems.Add(ap.PhysicalAddress.ToString());
                item.SubItems.Add(ap.SignalStrength.Decibels.ToString());
                item.SubItems.Add(ap.AuthenticationMode.ToString());
                listView1.Items.Add(item);
            }
            listView1.Refresh();
     }
吃颗糖壮壮胆 2024-09-21 13:03:19

您的代码实际上在主线程中运行。

listView1.Invoke(new APScanCallback(APScan));

此代码在主应用程序线程中提交 APScan 的执行。只需使用计时器代替工作线程即可。

Your code is actually running in the main thread.

listView1.Invoke(new APScanCallback(APScan));

This code submits execution of APScan in the main application thread. Just use the timer insteaf of worker thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文