1

我是 C# Windows Phone 编程新手。

简而言之,我目前正在构建一个应用程序,它将:

加载image A

加载image B

然后加载image C

然后使用这 3 张图像进行一些后期处理。

Content我的图像 B 和图像 C 是在项目中构建的。图像 A 是从图库中选择或通过相机拍摄的,或者我们可以简单地假设图像 A 是从独立存储中加载的。

我遇到了一个我认为是由异步图像加载引起的问题。

这是我的代码:

...
// I intend to load the 3 pictures by calling the method: LoadImage(int id) and LoadCImage();

            else if (ListBox.SelectedIndex == 0)
            {
                Debug.WriteLine("Selected 0");
                PhotoProcessor pp = new PhotoProcessor();
                WriteableBitmap imageA = new WriteableBitmap(AImage);
                WriteableBitmap imageB = LoadImage(0);
                WriteableBitmap imageC = LoadCImage();
                WriteableBitmap mix = pp.Mix(pp.CalcAverageColour(0), imageA, imageB, imageC);
                resultPic.Source = mix;
            }
...

和:

private WriteableBitmap LoadImage(int id)
        {
            //String uriString = "/Assets/img0.jpg";            
            //BitmapImage img = new BitmapImage(new Uri(uriString, UriKind.Relative));
            BitmapImage img = new BitmapImage();
            img.CreateOptions = BitmapCreateOptions.None;
            //img.SetSource(Application.GetResourceStream(new Uri("/Assets/facetemplate0.jpg", UriKind.Relative)).Stream);
            img.UriSource = new Uri("/Assets/img" + id + ".jpg", UriKind.Relative);

            //img.UriSource = new Uri(uriString, UriKind.Relative);
            return new WriteableBitmap(img);
        }

        private WriteableBitmap LoadCImage()
        {
            //BitmapImage img = new BitmapImage(new Uri("/Assets/imgC.jpg", UriKind.Relative));
            BitmapImage bmp = new BitmapImage();
            bmp.CreateOptions = BitmapCreateOptions.None;
            //img.SetSource(Application.GetResourceStream(new Uri("/Assets/imgC.jpg", UriKind.Relative)).Stream);
            bmp.UriSource = new Uri("/Assets/imgC.jpg", UriKind.Relative);
            return new WriteableBitmap(bmp);
        }

现在我的问题是:

当我试图运行这段代码时,它会抛出一个空引用异常,这是因为函数mix无法加载图像 AB 和 C(加载这些图像是异步的)。

我想知道是否有办法让我顺序加载这些图像然后让我将它们传递给mix函数?

我试过的:

  1. 通过查看这篇很棒的博客文章,我可以知道确实有一些方法可以同步加载图像,但是正如您在我的代码中看到的那样,我尝试SetSource(stream)像博客文章一样使用,但不幸的是我得到了相同的空引用例外。

  2. 我也考虑过这种EventHandler方法,但是在这种情况下我认为这不是一个好主意。如果我实现EventHandler,它会是这样的(伪代码):

    imageA_Opened()
    {
    LoadImageB += imageB_Opened();
    }
    
    imageB_Opened()
    {
     LoadImageC += imageC_Opened();
    }
    
    imageC_Opened()
    {
    PhotoProcessor pp = new PhotoProcessor();
    pp.Mix(averageColour, A, B, C);
    }
    

我对吗?

4

2 回答 2

2

Servy 说你不应该用同步调用阻塞 UI 是正确的。

话虽如此,我在 WP7 应用程序中也有类似的要求。我使用“Async CTP”来添加编写类似同步函数的功能,这些函数会等到它完成后再进行下一次调用。我的 API 调用需要来自早期调用的数据才能正常运行。

我相信这已包含在 .NET 4.5 中并适用于 WP8。

http://msdn.microsoft.com/en-ca/library/vstudio/hh191443.aspx

这是我为我的应用程序提取数据而写的内容(注意“ async ”和“ await ”关键字):

public async Task<bool> GetDefaultData()
{
    try
    {
        _cancellation = new CancellationTokenSource();

        UpdateProgress(DateTime.Now + ": Download Started.\n");
        List<string> data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetBaseDataUriList());
        App._apiConnection.Done(data);

        UpdateProgress(DateTime.Now + ": Countries: " + App._context.Countries.Count() + "\n");
        UpdateProgress(DateTime.Now + ": Regions: " + App._context.Regions.Count() + "\n");
        UpdateProgress(DateTime.Now + ": Income Levels: " + App._context.IncomeLevels.Count() + "\n");
        UpdateProgress(DateTime.Now + ": Indicators: " + App._context.Indicators.Count() + "\n");

        data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetCountryUriList("CA"));
        App._apiConnection.Done(data);
        UpdateProgress(DateTime.Now + ": CA Population: " + App._context.PopulationDatas.Count(c => c.Country.Iso2Code == "CA") + "\n");

        data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetCountryUriList("US"));
        App._apiConnection.Done(data);
        UpdateProgress(DateTime.Now + ": US Population: " + App._context.PopulationDatas.Count(c => c.Country.Iso2Code == "US") + "\n");

        data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetCountryUriList("CN"));
        App._apiConnection.Done(data);
        UpdateProgress(DateTime.Now + ": CN Population: " + App._context.PopulationDatas.Count(c => c.Country.Iso2Code == "CN") + "\n");

        return true;
    }
    catch (OperationCanceledException)
    {
        MessageBox.Show("Operation Cancelled");
        return false;



    }
    catch (Exception ex)
    {
        MessageBox.Show("getDefaultData Exception: " + ex.Message);

        return false;
    }
}
于 2012-12-13T15:01:25.223 回答
0

您不应该能够按顺序下载图像。是的,它肯定会更容易开发,但它不会那么有效,因为您会长时间阻塞处理器,从而冻结您的应用程序。

我也考虑过 EventHandler 方法,但是在这种情况下我认为这不是一个好主意。如果我实现 EventHandler,它会不会像(伪代码):

是的,它将遵循您所描述的一般模式。这是解决这个问题的适当方法。

于 2012-12-06T16:41:05.297 回答