繁体   English   中英

使同步代码取决于异步代码

[英]Making sync code depend on async code

在我当前的项目中,我将某些对象的状态存储在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进行交互,但这似乎也有些奇怪,因为它破坏了有关异步方法的整个想法。

好吧,您想await异步代码,而不是完全等待。 这将使您的GUI在加载数据时保持响应状态(并可能显示加载消息,具体取决于加载所需的时间)。

同步方法没有必要调用异步方法并等待 如果这样做,则可以首先使用sync方法,从而节省了开销。 您要一直保持异步状态(是的,这确实意味着您不希望在构造函数中加载数据,但是无论如何您都不应这样做)。

请注意,您可以在WinForms / WPF事件处理程序中await ,因此可以在这些LoadDataBinding事件等上滚动。

简而言之:当您发现自己有等待异步代码的同步代码时-您的设计可能存在缺陷。 在任何情况下,它都表明您正在忽略同步问题,而这些问题在您开始使用await时并不会神奇消失-访问全局变量仍然是一个非常糟糕的主意。 相反,您希望任务返回一个值(在您的情况下为Restaurant的可枚举值),并将其添加到UI线程中的全局列表中(即在被发布回同步上下文的延续中)。 现在,你实际上这样做,因为你正在处理的UI线程上的所有异步回调,但是这可能是不必要的,而且实际上可以是一个愚蠢的开销,使得装载需要更长的时间。

认为异步。 不要在旅途中停下来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM