我正在尝试使用以下代码连接到wifi:
private static bool ConnectToWifi(string profileName, WlanClient.WlanInterface wlanIface, Wifi wifi, string profile)
{
try
{
wlanIface.SetProfile(Wlan.WlanProfileFlags.AllUser, profile, true);
}
catch (Exception e)
{
var ex = e;
return false;
};
// Task.Run()
wlanIface.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Infrastructure, profileName);
Thread.Sleep(5000);
var status = wifi.ConnectionStatus;
var x = wlanIface.GetProfileXml(profileName);
if (status == WifiStatus.Disconnected)
{
return false;
}
return true;
}
我保持5000毫秒的延迟以确保网络连接,但这导致我的UI在执行此代码时不显示加载图标。
如何让我的UI同时更新,而不是等待连接?
答案 0 :(得分:2)
每当您在UI线程中执行Thread.Sleep
时,您都会中断处理所有UI消息,这会使您的UI无响应。因此,永远不应在UI线程中执行Thread.Sleep
和任何其他长时间运行的操作。
解决方案是在单独的线程中执行这些操作,以允许UI线程继续UI操作。让UI线程只进行UI操作通常是一个好主意。
在您的情况下,这意味着调用者应该在任务中执行操作:
private static bool ConnectToWifi(string profileName, WlanClient.WlanInterface wlanIface,
Wifi wifi, string profile, Action<bool> resultCallback, Dispatcher dispatcher)
{
//Your connect code
bool result;
if (status == WifiStatus.Disconnected)
{
result = false;
}
else
{
result = true;
}
dispatcher.BeginInvoke(() => resultCallback(result));
return result;
}
另一件事:Thread.Sleep
在任务中不是一个好主意,因为你不知道你正在运行哪个调度程序。您应该使用Task.Delay
代替。在这种情况下,Thread.Sleep
通常不是一个好主意,因为您只是等待并希望您的任务在五秒内完成,这是无法保证的。另外,如果用户立即连接,您可能只会浪费5秒的时间。更好的解决方案是使用等待循环并定期检查连接是否已建立。如果您希望连接在相当短的时间内发生,则可以使用SpinWait.SpinUntil
(超时为5秒):
SpinWait.SpinUntil(() => wifi.ConnectionStatus == WifiStatus.Connected, 5000);
答案 1 :(得分:2)
您有两种选择:
(两者都使得无法返回表示连接成功的bool而没有更多的逻辑。)
将代码移动到一个单独的线程(如果其余部分是线程安全的)并使用同步方法:
private static void ConnectToWifi(string profileName, WlanClient.WlanInterface wlanIface, Wifi wifi, string profile)
{
new Thread(()=>{
bool result = false;
try
{
wlanIface.SetProfile(Wlan.WlanProfileFlags.AllUser, profile, true);
wlanIface.ConnectSynchronously(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Infrastructure, profileName, 5000);
var status = wifi.ConnectionStatus;
var x = wlanIface.GetProfileXml(profileName);
result = (status != WifiStatus.Disconnected);
}
catch (Exception e)
{
var ex = e;
}
finally
{
Dispatcher.BeginInvoke(new Action(()=>{WhateverYouDoWithYourResult(result);}));
}
}).Start();
}
或订阅WlanConnectionNotification
(无法连接可能不会被视为更改,因此您必须对其进行测试):
private static bool ConnectToWifi(string profileName, WlanClient.WlanInterface wlanIface, Wifi wifi, string profile)
{
try
{
wlanIface.WlanConnectionNotification += Interface_ConnectionStateChanged;
wlanIface.SetProfile(Wlan.WlanProfileFlags.AllUser, profile, true);
wlanIface.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Infrastructure, profileName);
return true; //Just means the attempt was successful, not the connecting itself
}
catch (Exception e)
{
var ex = e;
return false;
}
}
private static void Interface_ConnectionStateChanged(Wlan.WlanNotificationData notifyData, Wlan.WlanConnectionNotificationData connNotifyData)
{
// Do something with that info, be careful - might not be the same thread as before.
}
我现在无法访问Wifi,所以我还没有对代码进行测试。它应该可以工作,但你最好把它看作伪代码而不是实际的现成解决方案。