загрузка Uri c # недетерминирована?

#c# #wpf #uri #bitmapimage

#c# #wpf #uri #растровое изображение

Вопрос:

Я пытаюсь загрузить некоторые растровые изображения из файлов, хранящихся в файловой системе. У меня есть словарь ключей и относительных путей к файлам. К сожалению, конструктор Uri кажется недетерминированным в том, как он будет загружать изображения.

Вот мой код:

 foreach(KeyValuePair<string, string> imageLocation in _imageLocations)
{
    try
    {
        BitmapImage img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri(@imageLocation.Value, UriKind.Relative);

        img.EndInit();
        _images.Add(imageLocation.Key, img);
    }
    catch (Exception ex)
    {
        logger.Error("Error attempting to load image", ex);

    }
}
  

К сожалению, иногда URI загружаются как относительные URI файлов, а иногда они загружаются как относительные URI пакетов. Кажется, нет какой-либо рифмы или причины относительно того, что будет загружено каким образом. Иногда я получаю, что все URI загружаются одним способом, или только пара, или большинство из них, и это будет меняться при каждом запуске кода.

Есть идеи, что здесь происходит?

Комментарии:

1. Можете ли вы воспроизвести это поведение в чистом тестовом проекте?

Ответ №1:

Ну, вроде того… В MSDN есть это, чтобы сказать о UriKind:

Абсолютные URI характеризуются полной ссылкой на ресурс (пример:http://www.contoso.com/index.html ), в то время как относительный Uri зависит от ранее определенного базового URI (пример: /index.html)

Если вы перейдете в reflector и посмотрите вокруг, вы увидите, что существует множество путей, по которым код может использовать, чтобы определить, каким должен быть относительный URI. В любом случае, дело не в том, что он недетерминирован, скорее это просто основной источник разочарования для многих разработчиков. Единственное, что вы можете сделать, это использовать класс ‘BaseUriHelper‘, чтобы разобраться в том, как решаются ваши uri.

С другой стороны, если вы знаете, где хранятся ваши ресурсы (а вы должны) Я бы посоветовал вам просто избавить себя от головной боли и использовать абсолютный URI для разрешения ваших ресурсов. Работает каждый раз, и никакого дурацкого кода за кулисами, который может сбить вас с толку, когда вы меньше всего этого ожидаете.

Комментарии:

1. Пути к моим ресурсам были относительными, а не абсолютными. Я решил конкретную проблему, с которой столкнулся, но решение кажется довольно дерьмовым.

2. да, спасибо, что воспользовались советом и дали себе ответ. Очень круто.

3. Если это делает вас настолько несчастным, вы можете поставить зеленую галочку:-p

Ответ №2:

В конце концов я решил проблему, получив базовый каталог моего приложения и добавив к нему относительный путь и используя абсолютный URI, а не относительный.

 string baseDir = AppDomain.CurrentDomain.BaseDirectory;

foreach(KeyValuePair<string, string> imageLocation in _imageLocations)
{
    try
    {
        BitmapImage img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri("file:///"   baseDir   @imageLocation.Value, UriKind.Absolute);

        img.EndInit();
        _images.Add(imageLocation.Key, img);
    }
    catch (Exception ex)
    {
        logger.Error("Error attempting to load image", ex);

    }
}
  

Комментарии:

1. Вы должны попробовать Path. Объединить(строка, string). msdn.microsoft.com/en-us/library/system.io.path.combine.aspx