【问题标题】:Async task raises NotImplementedException异步任务引发 NotImplementedException
【发布时间】:2015-05-07 20:52:26
【问题描述】:

我继续在 Windows Phone 编程方面苦苦挣扎。 :)

调用方法时:

public static async Task<string> ConvertToBase64(this BitmapImage bitmapImage)
{
    RandomAccessStreamReference rasr = RandomAccessStreamReference.CreateFromUri(bitmapImage.UriSource);
    var streamWithContent = await rasr.OpenReadAsync();
    byte[] buffer = new byte[streamWithContent.Size];
    var result = await streamWithContent.ReadAsync(buffer.AsBuffer(), (uint)streamWithContent.Size, InputStreamOptions.None);
    using (MemoryStream ms = new MemoryStream(result.ToArray()))
    {
        return Convert.ToBase64String(ms.ToArray());
    }
}

来自

public async void SetPhotoString(BitmapImage bi)
{
    photoBase64 = await bi.ConvertToBase64();
}

在类Offer中来自按钮回调:

public async void Post()
{
    var newOffer = new Offer()
    {
        BookAuthor = Author,
        BookTitle = Title,
        CurrencyWorth = Price,
        Description = Description,
        StartedAt = DateTime.UtcNow,
        Status = OfferStatus.Added
    };
    newOffer.SetPhotoString(Photo);//this line throws an excp.
    var result = await offerService.AddOffer(newOffer);
    if (result != null)
        ClearFormula();
}

我得到了“NotImplementedException”引发。我想我对异步调用做错了,但我不知道是什么。

异常详情: message: The method or operation is not implemented.

    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SecondHandBookshop.Shared.Helpers.BitmapImageExtensions.<ConvertToBase64>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SecondHandBookshop.Shared.Models.Offer.<SetPhotoString>d__0.MoveNext()

更多信息: Photo 是我的 AddNewOfferViewModel 的 BitmapImage 属性,它充当 Image 控件的源。它是从虚拟设备上的相机捕获的:

public async void TakeAPhoto()
    {
        ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();
        StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("TestPhoto.jpg",
            CreationCollisionOption.GenerateUniqueName);
        await _mediaCapture.CapturePhotoToStorageFileAsync(imgFormat, file);
        Photo = new BitmapImage(new Uri(file.Path));
        await MediaCapture.StopPreviewAsync();
        NotifyOfPropertyChange(() => Photo);
        ShowCaptureFrame = false;
        NotifyOfPropertyChange(() => ShowCaptureFrame);
    }

当我将给出和异常的行替换为:

newOffer.PhotoBase64 = await Photo.ConvertToBase64();

我得到一个例外:

    Additional information: Value does not fall within the expected range.

       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SecondHandBookshop.Shared.Helpers.BitmapImageExtensions.<ConvertToBase64>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SecondHandBookshop.WindowsPhone.ViewModels.AddOfferViewModel.<Post>d__1.MoveNext()

【问题讨论】:

  • 你能发布异常消息和堆栈跟踪吗?
  • Avoid async void methods - 我看不出你有任何理由想要 SetPhotoString 异步无效。
  • BitmapImage是通过摄像头抓图实现的。
  • @Damien_The_Unbeliever 我在使用newOffer.PhotoBase64 = await Photo.ConvertToBase64(); 时得到Additional information: Value does not fall within the expected range. 异常
  • @EmiliaSzymańska 你在哪里定义了Photo。这看起来很可疑,尤其是因为它是大写的。您确定要传递对象实例吗?

标签: c# windows-phone-8.1 async-await .net-4.5


【解决方案1】:

为什么没有等待您的ConvertToBase64 代码?这是完全错误的,因为async void 构造。

试着把你的代码改成这样:

newOffer.photoBase64 = await SetPhotoString(Photo);//this line throws an excp.

public async Task<string> SetPhotoString(BitmapImage bi)
{
    return await bi.ConvertToBase64();
}

另外,ConvertToBase64 方法的哪一行会引发异常?
连续操作是否会出现异常?
如果不是,那么您用于async 代码的某些类没有正确实现GetAwaiter 方法,这会导致您出现异常。
如果是,那么问题出在Photo 属性中,您没有向我们展示。可能是您的代码中有一些未实现的方法。

【讨论】:

  • 我将此标记为答案,因为真正的问题与异步调用无关,我发现异步调用是同步运行的。感谢帮助,我发布了另一个与base64转换有关的问题:stackoverflow.com/questions/30133552/…
【解决方案2】:

尝试在您的 ConvertToBase64 扩展方法中返回一个任务。

using (MemoryStream ms = new MemoryStream(result.ToArray()))
{
    return Task.FromResult(Convert.ToBase64String(ms.ToArray()));
}

【讨论】:

  • 这会导致编译器错误:Cannot convert type Task&lt;string&gt; to return type 'string'
  • 我在返回后立即忘记了 await 关键字。
  • 这让我回到未实现的异常。
  • 并像 VMAtm 所说的那样,将 await 关键字添加到您对 ConvertToBase64 的调用中。
猜你喜欢
  • 2019-04-12
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-25
  • 2018-07-01
  • 1970-01-01
相关资源
最近更新 更多