none
Dosya Kullanımda Hatası Çözüm Önerisi RRS feed

  • Soru

  • Merhabalar,

    Sorunum şu, bir servisim (Windows) anlık olarak gelen veriyi json formatında kayıt ediyor. Bir diğer servis (Windows ) ilgili path den bu dosyaları deserileze edip veritabanına kayıt ediyor, kayıt hatası alma ihtimaline kayıt edilen ve edilemeyen dosyaların path adreslerini aldığım için kayıt edilenleri siliyorum.

    İlk servis .json oluşturuyor.

            public static void JsonLocationData (LocationResult result, string IMEI)
            {
                try
                {
                    string path = ConfigurationManager.AppSettings["LocationPath"];
                    using (FileStream fs = File.Open(path + "\\" + IMEI + "_" + Guid.NewGuid() + ".json", FileMode.Create, FileAccess.Write, FileShare.Inheritable))
                    {
                        using (StreamWriter sw = new StreamWriter(fs))
                        {
                            using (JsonWriter jw = new JsonTextWriter(sw))
                            {
                                jw.Formatting = Formatting.Indented;
                                JsonSerializer serializer = new JsonSerializer();
                                serializer.Serialize(jw, result);
                               
                            }
                           
                        }
                        
                    }
                    JsonLocationAlarmData(result, IMEI);
                    JsonLocationArchiveData(result, IMEI);
                }
                catch (Exception ex)
                {
                    Logger.Logs.Log(ex.StackTrace + " --- Hata Açıklaması : ---" + ex.Message);
                }
            }

    İkinci servis .json okuyup kayıt ediyor.

    for (int i = 0; i < LocationFolderReader.Length; i++)
                    {
                        string jsonLocation=string.Empty;
                        using (System.IO.FileStream _StreamReader = new System.IO.FileStream(LocationFolderReader[i], FileMode.Open, FileAccess.Read, FileShare.Delete))
                        {
                            using (StreamReader sw = new StreamReader(_StreamReader))
                            {
                                jsonLocation = sw.ReadToEnd();
                            }
                        }
       Location location = Newtonsoft.Json.JsonConvert.DeserializeObject<Location>(jsonLocation);
                        _jLocationData.Add(location);
                    }

    2. servisin file stream 'ında ortalama 10 veriden 8'inde dosya kullanımda hatası alıyorum. Bu hatadan dolayı servisin durmaması için exceptionlarda sadece log oluşturuyorum. Ama bir sonraki döngüde bu dosyaları da veritabanına saliselik gecikme ile kayıt edebiliyorum. Ama doğal olarak log dosyamın boyutu bir hayli artıyor.

    Bir çok yol denememe rağmen maleysef bu hatadan kurtulamadım. Bu konuda yardım ve fikirlerinizi almak istiyorum.

    Şimdiden teşekkürler, mutlu yıllar.


    Fatih GÜRSOY

    30 Aralık 2016 Cuma 10:36

Yanıtlar

  • ilgili dizini her zaman kontrol edip,

    Ben seni tam anlayamamış olabilirim özür, ama dediğim şeyi tekrarlayacağım. diğer servisin "ilgili dizini her zaman kontrol etmesi" senin problemin. FileSystemWatcher bile kullanıyor olsan, dosyanın yazma işlemi tam olarak bitmemesine ramen sen dosyada değişiklik algılıyorsun, sorun bu. Tabiki using bloğu yada Close methodu stram ı kapatır ama daha kapatmadan diğer servis işleme başlamış oluyor.

    Şöyle düşün; internetten 500mb bi dosya indiriyorsun, klasörde görünüyor, ama gelmesi bitmemiş henüz. Dosyayı açmaya okumaya yada yazmaya çalıştığında hata alıyorsun, sendeki olay bunun çok hızlısı şeklinde oluyor.

    Dosya yazma işleminin bittiğini database'e veri yazan servise birinin söylemesi lazım, sonra harakete geçmesi lazım.

    Ben dosyayı yazan diğer servisimden, database e yazan servisime, TCP ile "benim dosya yazma işlemim bitti" anlamına gelen mesaj yolluyorum. Dosya değiişikliklerine bakmıyorum, anlatmak istediğim oydu.


    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com





    31 Aralık 2016 Cumartesi 15:14
    Moderatör

Tüm Yanıtlar

  • Hocam ,

    Benim bildiğim şu hata dosyaya biri yazarken okumaya  veya okurken yazmaya çalışıyor.Hocam aklıma gelen şey pc saatine göre yaz yada oku , saniye bilgisini al atıyorum ; saniye o an 30 dan büyükse oku , küçükse yaz gibi sınırlayabilirsin yada tabi yazılacak okunacak verinin büyüklüğüne göre sürede böyle ayarlana bilir.Biraz sığ bi çözüm oldu ama aklıma başka birşey gelirse yazarım.

    30 Aralık 2016 Cuma 11:31
  • Teşekkürler.

    Hatanın neyden kaynaklandığını biliyorum. Yukarıda da yazdığım gibi kaybettiğim saliseyi kazanmak için çözüm arıyorum. Bu yüzden zamandan bağımsız işlem yapmak durumundayım. Yinede teşekkürler.


    Fatih GÜRSOY

    30 Aralık 2016 Cuma 11:51
  • Her iki serviste senin ise neden dosyaya yazıyorsun? İki uygulama arasında iletişim kuracaksan "Named Pipeline" gibi yöntemleri kullanman performans ve güvenirlilik açısından daha iyi olacaktır.

    Yok ben illa ki böyle çözeceğim diyorsan. İlk stream'in file share parametresini inheritable den readwrite a çekip dene bakalım. Bu haliyle diğer processlere sen kitlemiş oluyorsun çünkü. 




    30 Aralık 2016 Cuma 16:47
  • Merhaba Cihan Bey, 

    Cevabınız için çok teşekkür ederim.Bu şekilde dosya yapısı ile çözmek veri kaybını önlemek için ve servislerin birbirine olan bağımlılığını anlıkta olsa engellemek için bir yol olarak düşündüm açıkçası.

    Şöyle ki ana servis durursa zaten sistem doğal olarak durur. Ama diğer servislerin durması geçmişe dönük veri kaybı yaratmayacağı için izlediğim bir yol. İlk tasarımımda tcp/ip üzerinden UDP protokolü kullanarak tasarladım ve uyguladım. Fakat bu sefer doğal olarak iki tane servis base servis oldu. 2. servis 1. servise bağımlı. Diğer tüm işlemler ise ikinci servise bağımlı.

    Bu sorumu sormadan evvel bir çok yol denedim. Bunlardan biride file share parametresini readwrite dahil değiştirmek.Ama malesef çözüm olmadı.Kodlarda bunun harici bahsettiğim hataya sebep olabilecek bir sebep görebiliyor musunuz? İlginiz için çok teşekkür ederim.


    Fatih GÜRSOY

    30 Aralık 2016 Cuma 17:25
  • Fatih; senin yöntemine benzer bir yöntemi bende kullanıyorum. Ama senden farklı olarak, ilk servis dosyayı göndermiyor, bunun yerine dosyayı kaydetme işlemini yapıyor bitirip stream'ını kapatıyor, "ben işimi bitirdim" anlamında tek bir byte gönderiyor gibi...

    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    30 Aralık 2016 Cuma 18:24
    Moderatör
  • Merhaba Önay Hocam,

    Hocam sanırım yanlış anlaşılma oldu veya ben sizi yanlış anlıyorum. İlk servis veriyi herhangi bir yere göndermiyor. İlgili dizinde dosyayı oluşturup içine veriyi yazıyor. Bu iki serviste aynı sunucumda. Diğer servis ilgili dizini her zaman kontrol edip, dosya var ise okuyup, veritabanına okuduğunu kayıt ediyor. Kayıt etme metodunda  True değeri alırsa o dosyayı siliyor.

    Hocam zaten Stream using bloğunda kullanılırsa kendini kapatmaz mı? Ben mi yanlış biliyorum?

    Önay hocam, ben cevabınızı anlayamadım. Rica etsem biraz daha detaylı açıklar mısınız?

     


    Fatih GÜRSOY


    • Düzenleyen fatihgrsy 31 Aralık 2016 Cumartesi 10:47
    30 Aralık 2016 Cuma 21:10
  • Önay Hocam, sevmediğim şeyi yapıp konu günceldir diyecem :)

    Fatih GÜRSOY

    31 Aralık 2016 Cumartesi 10:58
  • ilgili dizini her zaman kontrol edip,

    Ben seni tam anlayamamış olabilirim özür, ama dediğim şeyi tekrarlayacağım. diğer servisin "ilgili dizini her zaman kontrol etmesi" senin problemin. FileSystemWatcher bile kullanıyor olsan, dosyanın yazma işlemi tam olarak bitmemesine ramen sen dosyada değişiklik algılıyorsun, sorun bu. Tabiki using bloğu yada Close methodu stram ı kapatır ama daha kapatmadan diğer servis işleme başlamış oluyor.

    Şöyle düşün; internetten 500mb bi dosya indiriyorsun, klasörde görünüyor, ama gelmesi bitmemiş henüz. Dosyayı açmaya okumaya yada yazmaya çalıştığında hata alıyorsun, sendeki olay bunun çok hızlısı şeklinde oluyor.

    Dosya yazma işleminin bittiğini database'e veri yazan servise birinin söylemesi lazım, sonra harakete geçmesi lazım.

    Ben dosyayı yazan diğer servisimden, database e yazan servisime, TCP ile "benim dosya yazma işlemim bitti" anlamına gelen mesaj yolluyorum. Dosya değiişikliklerine bakmıyorum, anlatmak istediğim oydu.


    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com





    31 Aralık 2016 Cumartesi 15:14
    Moderatör
  • Çok teşekkür ederim. Anladım Önay Hocam. Yeni yılın sizlere sağlık ve huzur getirmesi dileklerimle.

    Mutlu yıllar.


    Fatih GÜRSOY

    31 Aralık 2016 Cumartesi 18:10