Universal App挂起在CreateFileAsync(可能死锁?)

时间:2016-05-24 08:23:23

标签: c# async-await deadlock

我正在制作一个程序,可以从相机中捕捉照片并使用它执行某些操作。所以我有以下代码(相机按钮处理程序和“一些操作”):

private async void btnCamera_Click(object sender, RoutedEventArgs e)
    {
        btnCamera.IsEnabled = false;

        var imgFormat = ImageEncodingProperties.CreateJpeg();
        var ocrFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;

        var imgFileRaw = await ocrFolder.CreateFileAsync("ocr_raw.jpg", CreationCollisionOption.ReplaceExisting);
        var imgFileFull = await ocrFolder.CreateFileAsync("ocr_full.jpg", CreationCollisionOption.ReplaceExisting);
        var imgFilePart = await ocrFolder.CreateFileAsync("ocr_part.jpg", CreationCollisionOption.ReplaceExisting);

        await camera.CapturePhotoToStorageFileAsync(imgFormat, imgFileRaw);
        await camera.StopPreviewAsync();

        await SaveImageEx(imgFileRaw, imgFileFull, false);
        await SaveImageEx(imgFileRaw, imgFilePart, true);

        this.Frame.GoBack();
    }

private async Task SaveImageEx(StorageFile SourceFile, StorageFile TargetFile, bool Partial)
    {
        using (var sourceStream = await SourceFile.OpenAsync(FileAccessMode.Read))
        using (var targetStream = await TargetFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            var decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, sourceStream);
            var encoder = await BitmapEncoder.CreateForTranscodingAsync(targetStream, decoder);

            bool rotated90Degrees = false;

            switch (previewOrientation)
            {
                case DisplayOrientations.Portrait:
                    {
                        encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
                        rotated90Degrees = true;
                        break;
                    }
                case DisplayOrientations.PortraitFlipped:
                    {
                        encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise270Degrees;
                        rotated90Degrees = true;
                        break;
                    }
                case DisplayOrientations.LandscapeFlipped:
                    {
                        encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise180Degrees;
                        break;
                    }
                case DisplayOrientations.Landscape:
                case DisplayOrientations.None:
                default:
                    {
                        encoder.BitmapTransform.Rotation = BitmapRotation.None;
                        break;
                    }
            }

            if (Partial)
            {
                encoder.BitmapTransform.Bounds = rotated90Degrees ?
                    RecognitionArea1.GetImageRegion(decoder.PixelHeight, decoder.PixelWidth) :
                    RecognitionArea1.GetImageRegion(decoder.PixelWidth, decoder.PixelHeight);
            }

            await encoder.FlushAsync();                   
        }

    }

问题是5-10次相机按钮点击代码中的1个挂起在行:

  

var imgFileRaw = await ocrFolder.CreateFileAsync(“ocr_raw.jpg”,   CreationCollisionOption.ReplaceExisting);

请有人解释一下我的代码出了什么问题?我已经阅读了很多例子,如何避免使用异步/等待操作死锁,我仍然不知道问题出在哪里。

UPDATE。似乎没有调用“SaveImageEx”没有挂起,仍然没有看到此方法中的任何危险。

UPDATE2。我用我在应用中真正使用的代码制作了最小的悬挂示例。只需单击相机按钮几次,您将在“CreateFileAsync”上看到死锁:

HangSample (Visual Studio 2013 solution)

0 个答案:

没有答案