为什么在等待声明后没有到达我的代码?

时间:2013-02-04 19:16:25

标签: wpf asynchronous

出于某种原因,我无法弄清楚,以下代码中的await语句之外的代码永远不会到达。为什么呢?

public class FileSystemUpdateSource : IUpdateSource
{
    private ObservableCollection<UpdatePackage> _packages = new ObservableCollection<UpdatePackage>();
    private readonly DirectoryInfo _importDirectory = null;


    public FileSystemUpdateSource(DirectoryInfo a_importDirectory)
    {
        #region Argument Validation

        if (a_importDirectory == null)
            throw new ArgumentNullException("a_importDirectory");

        #endregion

        _importDirectory = a_importDirectory;

        Refresh();
    }

    public ObservableCollection<UpdatePackage> Packages
    {
        get { return _packages; }
    }

    public async void RefreshAsync()
    {
        var task = new Task<IEnumerable<UpdatePackage>>(CreatePackages);

        var packages = await task;

        // *** Code not reached ***

        Packages.Clear();
        Packages.AddRange(packages);

    }

    public void Refresh()
    {
        var packages = CreatePackages();

        Packages.Clear();
        Packages.AddRange(packages);
    }

    private IEnumerable<UpdatePackage> CreatePackages()
    {
        var packageFiles = from packageFile in _importDirectory.EnumerateFiles().AsParallel()
                           where FileIsZip(packageFile)
                           select new UpdatePackage(packageFile);

        return packageFiles;
    }

    private bool FileIsZip(FileInfo a_file)
    {
        using (var fin = a_file.OpenRead())
        {
            byte[] firstBytes = new byte[5];
            fin.Read(firstBytes, 0, 5);

            if (firstBytes[0] == 80 && firstBytes[1] == 75 && firstBytes[2] == 3 && firstBytes[3] == 4 && firstBytes[4] == 20)
                return true;
            else
                return false;
        }
    }
}


    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var importRoot = ApplicationSettings.Current.GetValue("ImportRoot") as System.IO.DirectoryInfo;

        IUpdateSource updateSource = new FileSystemUpdateSource(importRoot);

        updateSource.RefreshAsync();

        // *** Code IS reached here. ***
    }

编辑

答案归功于在task.Start()之前将await添加到我的代码中(感谢Reed Copsey的回答):

    /// <summary>
    /// Refresh the list of available update packages (asynchronously).
    /// </summary>
    public async Task RefreshAsync()
    {
        var task = new Task<IEnumerable<UpdatePackage>>(CreatePackages);
        task.Start();

        var packages = await task;

        Packages.Clear();
        Packages.AddRange(packages);
    }

1 个答案:

答案 0 :(得分:2)

您正在错误地创建Task

当您致电new Task时,它无法启动任务。您应该使用Task.Run代替:

var task = Task.Run(CreatePackages);

这可以简化为:

public async void RefreshAsync()
{
    var packages = await Task.Run(CreatePackages);