2
2
using System . ComponentModel ;
3
3
using System . Diagnostics . Contracts ;
4
4
using System . IO . MemoryMappedFiles ;
5
+ using System . Runtime . Caching ;
5
6
using System . Threading ;
6
7
using System . Threading . Tasks ;
7
8
using System . Windows ;
@@ -14,24 +15,61 @@ public Photo(string f) {
14
15
this . ShortTitle = f ;
15
16
}
16
17
18
+ private WeakReference < BitmapImage > fullImageRef = null ;
19
+
20
+ private int fullIsLoading = 0 ;
21
+
22
+ private static CacheItemPolicy cachePolicy = new CacheItemPolicy ( ) {
23
+ SlidingExpiration = TimeSpan . FromSeconds ( 10 ) ,
24
+ } ;
25
+
17
26
public BitmapImage FullImage {
18
27
get {
19
- return ( BitmapImage ) GetValue ( FullImageProperty ) ;
28
+ var imageRef = this . fullImageRef ;
29
+ if ( imageRef != null && imageRef . TryGetTarget ( out BitmapImage target ) ) {
30
+ MemoryCache . Default . Set (
31
+ this . FileName ,
32
+ target ,
33
+ cachePolicy ) ;
34
+ return target ;
35
+ } else {
36
+ if ( Interlocked . Exchange ( ref this . fullIsLoading , 1 ) == 0 ) {
37
+ this . loader ? . EnqueueFullSizeRead ( this , this . setFrom ) ;
38
+ }
39
+ return this . ThumbImage ;
40
+ }
20
41
}
21
42
set {
22
- SetValue ( FullImageProperty , value ) ;
43
+ if ( value == null ) {
44
+ if ( Interlocked . Exchange ( ref this . fullImageRef , null ) != null ) {
45
+ this . PropertyChanged ? . Invoke ( this ,
46
+ new PropertyChangedEventArgs ( nameof ( FullImage ) ) ) ;
47
+ }
48
+ return ;
49
+ } else if ( this . fullImageRef == null ) {
50
+ this . fullImageRef = new WeakReference < BitmapImage > ( value ) ;
51
+ } else {
52
+ this . fullImageRef . SetTarget ( value ) ;
53
+ }
54
+ fullIsLoading = 0 ;
55
+ Thread . MemoryBarrier ( ) ;
56
+ this . PropertyChanged ? . Invoke ( this ,
57
+ new PropertyChangedEventArgs ( nameof ( FullImage ) ) ) ;
58
+ MemoryCache . Default . Set (
59
+ this . FileName ,
60
+ value ,
61
+ cachePolicy ) ;
23
62
}
24
63
}
25
- public static readonly DependencyProperty FullImageProperty =
26
- DependencyProperty . Register ( nameof ( FullImage ) ,
27
- typeof ( BitmapImage ) , typeof ( Photo ) ) ;
28
64
29
65
public BitmapImage ThumbImage {
30
66
get {
31
67
return ( BitmapImage ) GetValue ( ThumbImageProperty ) ;
32
68
}
33
69
set {
34
70
SetValue ( ThumbImageProperty , value ) ;
71
+ this . PropertyChanged ? . Invoke ( this ,
72
+ new PropertyChangedEventArgs ( nameof ( FullImage ) ) ) ;
35
73
}
36
74
}
37
75
public static readonly DependencyProperty ThumbImageProperty =
@@ -58,11 +96,13 @@ internal class Metadata {
58
96
}
59
97
60
98
private Metadata setFrom = null ;
99
+ internal ImageLoadManager loader = null ;
61
100
private bool setting = true ;
62
101
63
102
internal void Set ( Metadata from ) {
64
103
this . setting = true ;
65
104
this . setFrom = from ;
105
+ Thread . MemoryBarrier ( ) ;
66
106
if ( from . Title != null ) {
67
107
this . Title = from . Title ;
68
108
} else {
@@ -236,6 +276,7 @@ public void Dispose() {
236
276
Thread . MemoryBarrier ( ) ;
237
277
this . FullImage = null ;
238
278
this . ThumbImage = null ;
279
+ MemoryCache . Default . Remove ( this . FileName ) ;
239
280
ThreadPool . QueueUserWorkItem ( async _ => {
240
281
bool locked = false ;
241
282
try {
0 commit comments