OSDN Git Service

・キャッシュ画像のセーブ時にInvalidOperationExceptionが発生した場合、リトライするように修正
authoranis774 <anis774@users.sourceforge.jp>
Wed, 8 Sep 2010 16:12:28 +0000 (16:12 +0000)
committerKimura Youichi <kim.upsilon@bucyou.net>
Sat, 18 Feb 2012 14:15:17 +0000 (23:15 +0900)
・一時ファイルが作成されたことを確認してから保存するように修正
・CachedImageの排他処理を廃止、ImageCacheDictionaryで排他処理をするように変更

git-svn-id: http://svn.sourceforge.jp/svnroot/tween/trunk@831 e39ad16e-3079-482e-bb30-4b4d378143b6

Tween/ImageCacheDictionary.vb

index 45019fa..742d4cd 100644 (file)
@@ -9,9 +9,11 @@ Public Class ImageCacheDictionary
     Private sortedKeyList As List(Of String)    '古いもの順
 
     Public Sub New(ByVal memoryCacheCount As Integer)
-        Me.innerDictionary = New Dictionary(Of String, CachedImage)(memoryCacheCount + 1)
-        Me.sortedKeyList = New List(Of String)(memoryCacheCount + 1)
-        Me.memoryCacheCount = memoryCacheCount
+        SyncLock Me
+            Me.innerDictionary = New Dictionary(Of String, CachedImage)(memoryCacheCount + 1)
+            Me.sortedKeyList = New List(Of String)(memoryCacheCount + 1)
+            Me.memoryCacheCount = memoryCacheCount
+        End SyncLock
     End Sub
 
     Public Sub Add(ByVal item As System.Collections.Generic.KeyValuePair(Of String, Image)) Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Image)).Add
@@ -19,12 +21,14 @@ Public Class ImageCacheDictionary
     End Sub
 
     Public Sub Add(ByVal key As String, ByVal value As Image) Implements System.Collections.Generic.IDictionary(Of String, Image).Add
-        Me.innerDictionary.Add(key, New CachedImage(value))
-        Me.sortedKeyList.Add(key)
+        SyncLock Me
+            Me.innerDictionary.Add(key, New CachedImage(value))
+            Me.sortedKeyList.Add(key)
 
-        If Me.innerDictionary.Count > Me.memoryCacheCount Then
-            Me.innerDictionary(Me.sortedKeyList(Me.sortedKeyList.Count - Me.memoryCacheCount - 1)).Chache()
-        End If
+            If Me.innerDictionary.Count > Me.memoryCacheCount Then
+                Me.innerDictionary(Me.sortedKeyList(Me.sortedKeyList.Count - Me.memoryCacheCount - 1)).Chache()
+            End If
+        End SyncLock
     End Sub
 
     Public Function Remove(ByVal item As System.Collections.Generic.KeyValuePair(Of String, Image)) As Boolean Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Image)).Remove
@@ -32,59 +36,73 @@ Public Class ImageCacheDictionary
     End Function
 
     Public Function Remove(ByVal key As String) As Boolean Implements System.Collections.Generic.IDictionary(Of String, Image).Remove
-        Me.sortedKeyList.Remove(key)
-        Me.innerDictionary(key).Dispose()
-        Return Me.innerDictionary.Remove(key)
+        SyncLock Me
+            Me.sortedKeyList.Remove(key)
+            Me.innerDictionary(key).Dispose()
+            Return Me.innerDictionary.Remove(key)
+        End SyncLock
     End Function
 
     Default Public Property Item(ByVal key As String) As Image Implements System.Collections.Generic.IDictionary(Of String, Image).Item
         Get
-            Me.sortedKeyList.Remove(key)
-            Me.sortedKeyList.Add(key)
-            If Me.sortedKeyList.Count > Me.memoryCacheCount Then
-                Me.innerDictionary(Me.sortedKeyList(Me.sortedKeyList.Count - Me.memoryCacheCount - 1)).Chache()
-            End If
-            Return Me.innerDictionary(key).Image
+            SyncLock Me
+                Me.sortedKeyList.Remove(key)
+                Me.sortedKeyList.Add(key)
+                If Me.sortedKeyList.Count > Me.memoryCacheCount Then
+                    Me.innerDictionary(Me.sortedKeyList(Me.sortedKeyList.Count - Me.memoryCacheCount - 1)).Chache()
+                End If
+                Return Me.innerDictionary(key).Image
+            End SyncLock
         End Get
         Set(ByVal value As Image)
-            Me.sortedKeyList.Remove(key)
-            Me.sortedKeyList.Add(key)
-            If Me.sortedKeyList.Count > Me.memoryCacheCount Then
-                Me.innerDictionary(Me.sortedKeyList(Me.sortedKeyList.Count - Me.memoryCacheCount - 1)).Chache()
-            End If
-            Me.innerDictionary(key).Dispose()
-            Me.innerDictionary(key) = New CachedImage(value)
+            SyncLock Me
+                Me.sortedKeyList.Remove(key)
+                Me.sortedKeyList.Add(key)
+                If Me.sortedKeyList.Count > Me.memoryCacheCount Then
+                    Me.innerDictionary(Me.sortedKeyList(Me.sortedKeyList.Count - Me.memoryCacheCount - 1)).Chache()
+                End If
+                Me.innerDictionary(key).Dispose()
+                Me.innerDictionary(key) = New CachedImage(value)
+            End SyncLock
         End Set
     End Property
 
     Public Sub Clear() Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Image)).Clear
-        For Each value As CachedImage In Me.innerDictionary.Values
-            value.Dispose()
-        Next
+        SyncLock Me
+            For Each value As CachedImage In Me.innerDictionary.Values
+                value.Dispose()
+            Next
 
-        Me.innerDictionary.Clear()
-        Me.sortedKeyList.Clear()
+            Me.innerDictionary.Clear()
+            Me.sortedKeyList.Clear()
+        End SyncLock
     End Sub
 
     Public Function Contains(ByVal item As System.Collections.Generic.KeyValuePair(Of String, Image)) As Boolean Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Image)).Contains
-        Return Me.innerDictionary.ContainsKey(item.Key) AndAlso Me.innerDictionary(item.Key) Is item.Value
+        SyncLock Me
+            Return Me.innerDictionary.ContainsKey(item.Key) AndAlso Me.innerDictionary(item.Key) Is item.Value
+        End SyncLock
     End Function
 
     Public Sub CopyTo(ByVal array() As System.Collections.Generic.KeyValuePair(Of String, Image), ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Image)).CopyTo
-        Dim index As Integer = arrayIndex
-        For Each Item As KeyValuePair(Of String, CachedImage) In Me.innerDictionary
-            If array.Length - 1 < index Then
-                Exit For
-            End If
+        SyncLock Me
+            Dim index As Integer = arrayIndex
+            For Each Item As KeyValuePair(Of String, CachedImage) In Me.innerDictionary
+                If array.Length - 1 < index Then
+                    Exit For
+                End If
 
-            array(index) = New KeyValuePair(Of String, Image)(Item.Key, Item.Value.Image)
-            index += 1
-        Next
+                array(index) = New KeyValuePair(Of String, Image)(Item.Key, Item.Value.Image)
+                index += 1
+            Next
+        End SyncLock
     End Sub
 
     Public ReadOnly Property Count As Integer Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Image)).Count
         Get
-            Return Me.innerDictionary.Count
+            SyncLock Me
+                Return Me.innerDictionary.Count
+            End SyncLock
         End Get
     End Property
 
@@ -100,26 +118,32 @@ Public Class ImageCacheDictionary
 
     Public ReadOnly Property Keys As System.Collections.Generic.ICollection(Of String) Implements System.Collections.Generic.IDictionary(Of String, Image).Keys
         Get
-            Return Me.innerDictionary.Keys
+            SyncLock Me
+                Return Me.innerDictionary.Keys
+            End SyncLock
         End Get
     End Property
 
     Public Function TryGetValue(ByVal key As String, ByRef value As Image) As Boolean Implements System.Collections.Generic.IDictionary(Of String, Image).TryGetValue
-        If Me.innerDictionary.ContainsKey(key) Then
-            value = Me.innerDictionary(key).Image
-            Return True
-        Else
-            Return False
-        End If
+        SyncLock Me
+            If Me.innerDictionary.ContainsKey(key) Then
+                value = Me.innerDictionary(key).Image
+                Return True
+            Else
+                Return False
+            End If
+        End SyncLock
     End Function
 
     Public ReadOnly Property Values As System.Collections.Generic.ICollection(Of Image) Implements System.Collections.Generic.IDictionary(Of String, Image).Values
         Get
-            Dim imgList As New List(Of Image)(Me.memoryCacheCount)
-            For Each value As CachedImage In Me.innerDictionary.Values
-                imgList.Add(value.Image)
-            Next
-            Return imgList
+            SyncLock Me
+                Dim imgList As New List(Of Image)(Me.memoryCacheCount)
+                For Each value As CachedImage In Me.innerDictionary.Values
+                    imgList.Add(value.Image)
+                Next
+                Return imgList
+            End SyncLock
         End Get
     End Property
 
@@ -134,9 +158,11 @@ Public Class ImageCacheDictionary
     End Function
 
     Public Sub Dispose() Implements IDisposable.Dispose
-        For Each item As CachedImage In Me.innerDictionary.Values
-            item.Dispose()
-        Next
+        SyncLock Me
+            For Each item As CachedImage In Me.innerDictionary.Values
+                item.Dispose()
+            Next
+        End SyncLock
     End Sub
 
     Private Class CachedImage
@@ -144,7 +170,6 @@ Public Class ImageCacheDictionary
 
         Private img As Image = Nothing
         Private tmpFilePath As String = Nothing
-        Private Shared lockObject As New Object
 
         Public Sub New(ByVal img As Image)
             Me.img = img
@@ -152,27 +177,36 @@ Public Class ImageCacheDictionary
 
         Public ReadOnly Property Image As Image
             Get
-                SyncLock lockObject
-                    If Me.img Is Nothing Then
-                        Me.img = Image.FromFile(Me.tmpFilePath)
-                    End If
+                If Me.img Is Nothing Then
+                    Me.img = Image.FromFile(Me.tmpFilePath)
+                End If
 
-                    Return Me.img
-                End SyncLock
+                Return Me.img
             End Get
         End Property
 
         Public Sub Chache()
-            SyncLock lockObject
-                If Me.tmpFilePath Is Nothing Then
-                    Me.tmpFilePath = Path.GetTempFileName()
-                    Me.img.Save(Me.tmpFilePath)
-                End If
-                If Me.img IsNot Nothing Then
-                    Me.img.Dispose()
-                    Me.img = Nothing
-                End If
-            End SyncLock
+            If Me.tmpFilePath Is Nothing Then
+                Me.tmpFilePath = Path.GetTempFileName()
+
+                While Not File.Exists(Me.tmpFilePath)
+                End While
+
+                Dim err As Boolean = False
+                Do
+                    Try
+                        err = False
+                        Me.img.Save(Me.tmpFilePath)
+                    Catch ex As InvalidOperationException
+                        err = True
+                    End Try
+                Loop While err
+
+            End If
+            If Me.img IsNot Nothing Then
+                Me.img.Dispose()
+                Me.img = Nothing
+            End If
         End Sub
 
         Public Sub Dispose() Implements IDisposable.Dispose