Skip to content

Commit a3b25d1

Browse files
committed
Add retry logic for thumbnail loading
1 parent 1f94b87 commit a3b25d1

File tree

1 file changed

+69
-53
lines changed

1 file changed

+69
-53
lines changed

Flow.Launcher.Infrastructure/Image/ImageLoader.cs

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ private enum ImageType
100100

101101
private static ImageResult LoadInternal(string path, bool loadFullImage = false)
102102
{
103-
ImageSource image;
104-
ImageType type = ImageType.Error;
103+
ImageResult imageResult;
104+
105105
try
106106
{
107107
if (string.IsNullOrEmpty(path))
@@ -125,78 +125,94 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false)
125125
path = Path.Combine(Constant.ProgramDirectory, "Images", Path.GetFileName(path));
126126
}
127127

128-
if (Directory.Exists(path))
128+
imageResult = GetThumbnailResult(ref path, loadFullImage);
129+
}
130+
catch (System.Exception e)
131+
{
132+
try
133+
{
134+
// Retry to get thumbnail for certain images when the first try failed
135+
imageResult = GetThumbnailResult(ref path, loadFullImage);
136+
}
137+
catch (System.Exception e2)
129138
{
130-
/* Directories can also have thumbnails instead of shell icons.
131-
* Generating thumbnails for a bunch of folders while scrolling through
132-
* results from Everything makes a big impact on performance and
133-
* Flow.Launcher responsibility.
134-
* - Solution: just load the icon
135-
*/
136-
type = ImageType.Folder;
137-
image = WindowsThumbnailProvider.GetThumbnail(
138-
path,
139-
Constant.ThumbnailSize,
140-
Constant.ThumbnailSize,
141-
ThumbnailOptions.IconOnly);
139+
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
140+
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
142141

142+
ImageSource image = _imageCache[Constant.ErrorIcon];
143+
_imageCache[path] = image;
144+
imageResult = new ImageResult(image, ImageType.Error);
143145
}
144-
else if (File.Exists(path))
146+
}
147+
148+
return imageResult;
149+
}
150+
151+
private static ImageResult GetThumbnailResult(ref string path, bool loadFullImage = false)
152+
{
153+
ImageSource image;
154+
ImageType type = ImageType.Error;
155+
156+
if (Directory.Exists(path))
157+
{
158+
/* Directories can also have thumbnails instead of shell icons.
159+
* Generating thumbnails for a bunch of folders while scrolling through
160+
* results from Everything makes a big impact on performance and
161+
* Flow.Launcher responsibility.
162+
* - Solution: just load the icon
163+
*/
164+
type = ImageType.Folder;
165+
image = GetThumbnail(path, ThumbnailOptions.IconOnly);
166+
}
167+
else if (File.Exists(path))
168+
{
169+
var extension = Path.GetExtension(path).ToLower();
170+
if (ImageExtensions.Contains(extension))
145171
{
146-
var extension = Path.GetExtension(path).ToLower();
147-
if (ImageExtensions.Contains(extension))
172+
type = ImageType.ImageFile;
173+
if (loadFullImage)
148174
{
149-
type = ImageType.ImageFile;
150-
if (loadFullImage)
151-
{
152-
image = LoadFullImage(path);
153-
}
154-
else
155-
{
156-
/* Although the documentation for GetImage on MSDN indicates that
157-
* if a thumbnail is available it will return one, this has proved to not
158-
* be the case in many situations while testing.
159-
* - Solution: explicitly pass the ThumbnailOnly flag
160-
*/
161-
image = WindowsThumbnailProvider.GetThumbnail(
162-
path,
163-
Constant.ThumbnailSize,
164-
Constant.ThumbnailSize,
165-
ThumbnailOptions.ThumbnailOnly);
166-
}
175+
image = LoadFullImage(path);
167176
}
168177
else
169178
{
170-
type = ImageType.File;
171-
image = WindowsThumbnailProvider.GetThumbnail(
172-
path,
173-
Constant.ThumbnailSize,
174-
Constant.ThumbnailSize,
175-
ThumbnailOptions.ThumbnailOnly);
179+
/* Although the documentation for GetImage on MSDN indicates that
180+
* if a thumbnail is available it will return one, this has proved to not
181+
* be the case in many situations while testing.
182+
* - Solution: explicitly pass the ThumbnailOnly flag
183+
*/
184+
image = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly);
176185
}
177186
}
178187
else
179188
{
180-
image = _imageCache[Constant.ErrorIcon];
181-
path = Constant.ErrorIcon;
182-
}
183-
184-
if (type != ImageType.Error)
185-
{
186-
image.Freeze();
189+
type = ImageType.File;
190+
image = GetThumbnail(path, ThumbnailOptions.None);
187191
}
188192
}
189-
catch (System.Exception e)
193+
else
190194
{
191-
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e);
192-
type = ImageType.Error;
193195
image = _imageCache[Constant.ErrorIcon];
194-
_imageCache[path] = image;
196+
path = Constant.ErrorIcon;
197+
}
198+
199+
if (type != ImageType.Error)
200+
{
201+
image.Freeze();
195202
}
196203

197204
return new ImageResult(image, type);
198205
}
199206

207+
private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly)
208+
{
209+
return WindowsThumbnailProvider.GetThumbnail(
210+
path,
211+
Constant.ThumbnailSize,
212+
Constant.ThumbnailSize,
213+
option);
214+
}
215+
200216
public static ImageSource Load(string path, bool loadFullImage = false)
201217
{
202218
var imageResult = LoadInternal(path, loadFullImage);

0 commit comments

Comments
 (0)