我想做的是:-在第一页加载之前,同步(甚至异步)从USB驱动器加载设置。
我所做的:-在OnLaunched App.xaml.cs方法中,我调用了这个静态函数:
public static async void LoadSettings(string folderName = "Config", string fileName = "Settings.xml")
{
try
{
StorageFile configFile = null;
// scan through all devices
foreach (var device in await KnownFolders.RemovableDevices.GetFoldersAsync().AsTask().ConfigureAwait(false))
{
// folder that should have configuration
var configFolder = await device.GetFolderAsync(folderName).AsTask().ConfigureAwait(false);
if (configFile != null && configFolder != null && await configFolder.GetFileAsync(fileName).AsTask().ConfigureAwait(false) != null)
{
throw new Exception("More than one configuration file detected. First found configuration file will be used.");
}
else
configFile = await configFolder.GetFileAsync(fileName).AsTask().ConfigureAwait(false);
}
if (configFile == null)
throw new Exception("Configuration file was not found, please insert device with proper configuration path.");
string settingString = await FileIO.ReadTextAsync(configFile).AsTask().ConfigureAwait(false);
XmlSerializer serializer = new XmlSerializer(typeof(Settings));
using (TextReader reader = new StringReader(settingString))
{
AppSettings = (Settings)serializer.Deserialize(reader); // store settings in some static variable
}
}
catch (Exception e)
{
//return await Task.FromResult<string>(e.Message);
}
//return await Task.FromResult<string>(null);
}正如您现在所看到的,它是异步空方法,所以我甚至不想以任何方式将它与UI线程同步。它应该开火然后做点什么。使用ConfigureAwait(false),我希望确保它永远不会试图返回上下文。最后,这些返回是我尝试过的其他东西的残余(我希望这样做更好,这是最原始的解决方案,但仍然无法工作)。
无论如何,这就是乐趣的开始:当我用Win 10在本地机器上调试应用程序时,一切都运行得很好。在Raspberry Pi 3上安装的Win 10 IOT (我今天从零开始安装它,最后一个版本)上,我得到了死死的线程。
但僵局并不是最奇怪的事情。最奇怪的是它出现的时候。
正如我所说,调用此方法如下所示:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Configuration.Settings.LoadSettings();在此之后,此方法中的所有内容都将正常进行,因此我导航到下面的第一页:
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(LogScreen), e.Arguments);
}
Window.Current.Activate();
}一切都还能用。用户需要编写他的代码,我检查这段代码在设置中是否可用,然后该用户可以按"OK“键移动到下一页。在LogScreenViewModel的某个地方,这个方法负责:
private void GoForward(bool isValid)
{
try
{
_navigationService.NavigateTo("MainPage"); // it's SimpleIoc navigation from MVVMLight
}
catch (Exception e)
{
Debug.WriteLine($"ERROR: {e.Message}");
}
}当到达_navigationService.NavigateTo("MainPage")时会发生死锁。基本上现在UI线程冻结了。如果等待足够长的时间,我将在输出中看到捕获的异常,说明信使似乎占为己有(我现在无法显示屏幕,因为我无法访问那个Raspberry ),在超时之后,这个线程被杀死(大约30秒或更多)--在UI线程解锁和应用程序继续到MainPage之后。它不会发生在PC上-- MainPage立即出现,没有例外,没有死锁。
我试着在第一页上等待大约1分钟,以检查某些死锁异常是否会自动触发--但它不会。只有在我尝试继续到下一页时,它才会触发。
我还尝试了什么来代替这种“火与忘”的方法:
Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => await Configuration.Settings.LoadSettings(); ).AsTask().Wait(); --如果我记得正确的话,它就会立即陷入僵局,即使在ConfigureAwait(false)无处不在,但它也发生在PC上。我遗漏了什么?我还能做什么呢?因为老实说,在我看来,Win 10 IOT .NET运行时被窃听了什么的。
发布于 2018-11-26 13:14:28
我想我解决了这个问题。一般来说,这段代码不是我的,在深入挖掘之后,我注意到在我之前有人试图在导航到MainPage时列出其他一些外部设备。它并不是真正的异步安全代码(可能有人不知道同步上下文),它只在Win 10上工作,因为它在桌面上寻找COM0设备,而我只有COM2,所以根本没有调用引起麻烦的方法。
我仍然不知道它与我的配置有多关联(因为它在某种程度上没有它的作用),但是在我修复了这个旧的不异步安全代码的问题之后,它开始像预期的那样运行。
https://stackoverflow.com/questions/53452095
复制相似问题