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时,它没有做任何事情,也没有找到任何设备.在我评论出该帖子之后,它就有效了.有谁知道原因?我想以与搜索设备相同的形式执行其他操作.
看一下使用BackgroundWorker线程:
我怀疑你遇到的问题是你正在创建的线程中,你试图将你的结果立即绑定到你的UI控件.基本上,当您创建这样的线程时,不允许与任何UI元素通信,因为它们位于不同的线程上.
在您的情况下,我将创建一个BackgroundWorker,将上述大部分代码放在填充列表的DoWork方法中,然后在RunWorkerCompleted方法中将"Lists <>"绑定到用户控件.
Compact Framework 3.5的更新:
您仅限于使用Thread.Start和Timer进行线程化:
这看起来更像你要做的事情:
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)