Lecture d'un fichier par 2 processus : Comment éviter les erreurs d'accès concurrents ?
Hello,
Je plante le décor :
J'ai une appli winforms qui va écrire des trucs dans un fichier texte (elle fait d'autres trucs mais sans importance pour la problématique) dans un répertoire précis. A côté de ça, il y a un service qui surveille le répertoire en question et à chaque fois qu'un fichier y est créé ou modifié, en fait une copie vers un autre serveur (situé en Allemagne).
N.B. : Chaque utilisateur a son fichier donc pas de problème d'accès concurrent par différents utilisateurs, c'est déjà ça...
L'opération du service est assez rapide mais de temps en temps, quand j'ai un utilisateur qui sait ce qui est un minimum organisé et, du coup, va plus vite que les autres, j'ai une erreur dans l'appli winforms à l'écriture dans le fichier car il est toujours utiliser par le service qui fait la copie.
Du coup, hier, j'ai ajouté dans la couche métier de l'appli winforms les lignes 20 à 22 de la Sub ci-dessous et la fonction IsFileLocked :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| Public Sub ExportToFile(ByVal sequenceNumber As Integer)
Dim t As Date = Now
Dim d As Date
If t.TimeOfDay.Hours < 8 Then
d = Today.AddDays(-1)
Else
d = Today
End If
Dim fileName As String = "TR" & d.Year.ToString.Substring(2, 2) & d.Month.ToString("00") & d.Day.ToString("00") & ".txt"
Dim sw As IO.StreamWriter
Dim storageFolder As String = New IO.StreamReader("BLL.conf").ReadLine
If Not IO.Directory.Exists(storageFolder & "\" & Me.DTO.Store.Code & "\") Then
IO.Directory.CreateDirectory(storageFolder & "\" & Me.DTO.Store.Code & "\")
End If
While IsFileLocked(New IO.FileInfo(storageFolder & "\" & Me.DTO.Store.Code & "\" & fileName))
Threading.Thread.Sleep(1000)
End While
sw = New IO.StreamWriter(storageFolder & "\" & Me.DTO.Store.Code & "\" & fileName, True)
Dim line As String
'setting de line
sw.WriteLine(line)
sw.Close()
sw.Dispose()
End Sub
Private Function IsFileLocked(file As IO.FileInfo) As Boolean
Dim stream As IO.FileStream = Nothing
Try
stream = file.Open(IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.None)
Catch ex As Exception
Return True
Finally
If stream IsNot Nothing Then
stream.Close()
End If
End Try
Return False
End Function |
A priori, en cas de fichier encore utilisé, on patiente une seconde et on retente. Sauf que avec cette modif, j'ai ceci dans le journal des évènements ou l'application tourne :
Citation:
The program SEALBAG_GUI.exe version 1.0.0.0 stopped interacting with Windows and was closed. To see if more information about the problem is available, check the problem history in the Action Center control panel.
Je n'ai malheureusement pas vu de mes propres yeux ce qui se passent mais j'imagine que doit être ce qu'il se passe quand un programme "freeze" et que windows affiche "Not responding". Par contre, pourquoi windows ferme-t-il mon appli et n'attend pas qu'elle réponde à nouveau ??