需要帮助让线程在WinForm中工作

Cha*_*LAU 0 c# thread-safety .net-3.5 winforms

在我的智能设备应用程序中,我有搜索所有可发现的蓝牙设备并使用Windows Mobile 6.5连接到设备的功能.当我按下按钮搜索蓝牙设备时,UI冻结,我无法做任何其他事情.在找到所有可发现的设备之后,UI再次响应.

我知道我应该使用线程来处理这个问题.但是,我没有成功地让它发挥作用.

这是我用于搜索蓝牙设备的代码.在代码中,我有两个BindingLists.一个是DiscoverableDevices,另一个是ConnectedSEMDevices,它们分别绑定到列表框和组合框.

    private void SearchBTDevices()
    {
     // Thread thread = new Thread(new ThreadStart(delegate{
        List<BluetoothDevice> list = new List<BluetoothDevice>();
        this.discoverableDevices.Clear();  //DiscoverableDevices is binding to the form
        list.foreach(x => this.Discoverable.Add(x));
        ConnectedSEMDevices.Clear()
        list.Where(x => x.HasAuthenticated).ToList().ForEach(x => ConnectedSEMDevices.Add(x));  // ConnectedSEMDevices is binding to the Form
     // }));
     // thread.Start();
    }
Run Code Online (Sandbox Code Playgroud)

当我在上面的代码中取消注释掉Thread时,它没有做任何事情,也没有找到任何设备.在我评论出该帖子之后,它就有效了.有谁知道原因?我想以与搜索设备相同的形式执行其他操作.

Bra*_*Rem 5

看一下使用BackgroundWorker线程:

MSDN - BackgroundWorker

我怀疑你遇到的问题是你正在创建的线程中,你试图将你的结果立即绑定到你的UI控件.基本上,当您创建这样的线程时,不允许与任何UI元素通信,因为它们位于不同的线程上.

在您的情况下,我将创建一个BackgroundWorker,将上述大部分代码放在填充列表的DoWork方法中,然后在RunWorkerCompleted方法中将"Lists <>"绑定到用户控件.

Compact Framework 3.5的更新:

您仅限于使用Thread.Start和Timer进行线程化:

Compact Framework中的线程化

这看起来更像你要做的事情:

Microsoft .NET Compact Framework多线程提示

在那种情况下,我会回到你正在做的事情.我对您的代码片段感到担心的是,似乎没有方法调用实际获得蓝牙设备的方法.这是我要开始的地方:

private void SearchBTDevices()
{
    Thread thread = new Thread(new ThreadStart(delegate
    {
        List<BluetoothDevice> list = new List<BluetoothDevice>();

        // isn't there some method you have that populates your List<BluetoothDevices>????
        list = FindMeMyBluetoothDevices();

        this.Invoke(new MethodInvoker(() => 
        {
            this.discoverableDevices.Clear();
            list.ForEach(x => this.discoverableDevices.Add(x)); 
        }));

        this.Invoke(new MethodInvoker(() => 
        {
            ConnectedSEMDevices.Clear();
            list.Where(x => x.HasAuthenticated).ToList().ForEach(x => ConnectedSEMDevices.Add(x)); 
        }));
    }));

    thread.Start();
} 
Run Code Online (Sandbox Code Playgroud)