tags:

views:

153

answers:

2

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);
            }

        }
+2  A: 

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();
     }
Luca
Thanks a lot, it works. is it because my code calls the APScan() to execute in UI thread? so i should put the while statement in the scanThread then the app only freezes at the time of executing the code in APScan()?
seekinghelp
btw, is there a way that the app never freezes when updating listview?
seekinghelp
@seekinghelp The app doesn't freeze. The UI thread execute routines; more time taken from these routines corresponds to slower UI update. Infinite loops in UI routines always freeze UI updater thread.
Luca
OK, gotcha, thanks again
seekinghelp
A: 

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.

Alex Farber
Timers are supported in .NET Compact Framework?
Luca
Hi, Alex, Luca's suggestion works for me, but I will do some study on the timer to see how it can slove my problem.Thank you
seekinghelp