在我当前的项目中,我将某些对象的状态存储在XML文件中。当我在WPF项目中工作时,我需要使用异步方法执行此操作。
因为我在加载应用程序时遇到了问题。我是从XML文件重新创建这些对象的状态,这些文件必须是异步的,但我的内容取决于这些对象的状态,在我的情况下导致对象在我之前没有完全实例化与他们合作。
简而言之:我的同步方法取决于启动应用程序时实例化对象的异步方法。
下面是一些代码,显示了我如何读取整个文件夹的xml文件并生成对象列表。
public List<Restaurant> restaurant = new List<Restaurant>();
public async void ReadRestaurantAsync()
{
IStorageFolder filesFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("folder");
var storageFiles = await filesFolder.GetFilesAsync();
foreach (var storageFile in storageFiles)
{
using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read))
using (Stream inputStream = stream.AsStreamForRead())
{
DataContractSerializer serializer = new DataContractSerializer(typeof (Restaurant));
Restaurant objectRead = serializer.ReadObject(inputStream) as Restaurant;
restaurant.Add(objectRead);
}
}
}
现在当我从我的MainPage调用这个异步方法时,我无法使用对象Restaurant,因为它尚未完全实例化。
我猜我在尝试与Restaurant进行交互之前必须等待完全执行的方法,但这似乎有点奇怪,因为它破坏了关于异步方法的整个想法。
答案 0 :(得分:2)
嗯,你想要await
异步代码,而不是等待。这将在您加载数据时保持GUI响应(并且可能显示加载消息,具体取决于加载所需的时间)。
同步方法调用异步方法和等待没有意义。如果您正在执行此操作,则可以首先使用同步方法并节省开销。你希望一直保持异步(是的,这确实意味着你不想在构造函数中加载数据 - 但你不应该这样做)。
请注意,您可以在WinForms / WPF事件处理程序中await
正常运行,因此请继续查看Load
和DataBinding
个事件等。
简而言之:当您发现自己有同步代码等待异步代码时 - 您的设计可能存在缺陷。在任何情况下,它都表明你忽略了同步问题等等,当你开始使用await
时,它们不会神奇地消失 - 访问全局变量仍然是一个非常糟糕的主意。相反,您希望任务返回一个值(在您的情况下,可枚举Restaurant
)并将这些值添加到UI线程中的全局列表中(即,在发布回同步上下文的延续中) )。现在,你 实际上正在这样做,因为你正在处理UI线程上的所有异步回调,但这可能是不必要的,实际上可能是一个愚蠢的开销,使得装载需要更长时间。
思考异步。不要在旅途中停下来。