2011-08-28 11 views
8

kodu:Neden com bağlantı noktasına erişim reddedildi?

static void Main(string[] args) 
{ 
    Console.WriteLine("Memory mapped file reader started"); 

    using (var file = MemoryMappedFile.OpenExisting("AIDA64_SensorValues")) 
    { 
     using (var readerz = file.CreateViewAccessor(0, 0)) 
     { 
      var bytes = new byte[567]; 
      var encoding = Encoding.ASCII; 
      readerz.ReadArray<byte>(0, bytes, 0, bytes.Length); 

      File.WriteAllText("C:\\myFile.txt", encoding.GetString(bytes)); 

      var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; 
      using (var reader = XmlReader.Create("C:\\myFile.txt", readerSettings)) 
      { 
       while (reader.Read()) 
       { 
        using (var fragmentReader = reader.ReadSubtree()) 
        { 
         if (fragmentReader.Read()) 
         { 

          reader.ReadToFollowing("value"); 
          SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 
          port.Open(); 
          port.Write(reader.ReadElementContentAsString() + ","); 
         } 
        } 
       } 
      }  
     } 
    } 

    Console.WriteLine("Press any key to exit ..."); 
    Console.ReadLine(); 
} 

o paylaşılan hafızayı okur paylaşılan bellek daha sonra aynı dosya xml okuyucu ile açıldığında, dosya yazıyor ve birden çok kökleri vardır çünkü xml böler, sonra bir düğümün değerini alır Her yeni bölünmüş xml ve seri üzerinden gönderir. ilk bölünmüş xml üzerinde çalışır ve düğümü seri üzerinden gönderilir, daha sonra seriye ikinci düğümün yazılması girişimi sırasında com port mesajına erişim engellenir.

Aynı seri kodla yaptığım başka bir uygulama var ve gayet iyi çalışıyor (sadece yoruldum sonra kapattım.) ... bu yüzden tuhaf.

+0

belki de bazı referansları düzgün bir şekilde kapatmıyorsunuz ve aynı app/thread'dan daha fazla erişimi reddetmek için accessor aracı açılmıyor mu? –

cevap

21

sadece bir kez seri port açabilirsiniz Bu kodu değiştirin. Ancak kodunuz while döngüsünde Open() çağrısına sahiptir. Bu sadece ilk geçiş için çalışacaktır, 2. geçişte kaboom. @ cdhowie'nin çözümü de işe yaramıyor, SerialPort'un belgelerin uyardığı bir tuhaflığı var. Bir iş parçacığının, Dispose() veya Close() çağrısından sonra çıkmak için zamana ihtiyacı vardır. Zaman miktarı belirtilmemiş ve tahmin edilemez.

Gerçek çözüm basittir, while döngüsünden önce Open() çağrısını taşıyın. Hans'ın cevap ilaveten

+0

EVET !!! teşekkür ederim! – Csharpz

0

Hans'ın cevabı bu konuyu ele alıyor; Bunu sadece içerik ve bilgilendirme amaçlı bırakıyorum.


İşiniz bittiğinde bağlantı noktasını kapatmanız gerekir. Başka bir tanıtıcı açmaya çalışmadan önce çöp toplayıcı ilk SerialPort nesnesini toplamaz.

SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 
port.Open(); 
port.Write(reader.ReadElementContentAsString() + ","); 

için:

using (SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One))) 
{ 
    port.Open(); 
    port.Write(reader.ReadElementContentAsString() + ","); 
} 
+3

Bu da, SerialPort quirk çalışmıyor. –

+0

Hmm, bu ilginç. Cevabımı bilgi sebeplerinden dolayı terk ediyorum. – cdhowie

2

:

Ben aynı sorunu vardı ve açılış ve seri port kapanış arasında bazı uyku süreleri ile biraz etrafına oynadı. Benim durumumda 250 ms yeterliydi. Belki bu birileri dışarıda yardımcı olacaktır.

DÜZENLEME:

benim çözüm optimize edilmiş ve bu ben ile geldi budur:

int maxRetries = 20; 
const int sleepTimeInMs = 50; 
string loggingMessage = string.Empty; 

while (maxRetries > 0) 
{ 
    try 
    { 
     loggingMessage = "Opening serial port '" + mSerialPort.PortName + "'..."; 
     mSerialPort.Open(); 
     loggingMessage += "Succeeded."; 
     IOLogger.LogInfo(loggingMessage); 
    } 
    catch (UnauthorizedAccessException unauthorizedAccessException) 
    { 
     maxRetries--; 
     loggingMessage += "Failed (UnauthorizedAccessException): "; 
     IOLogger.LogError(string.Format(loggingMessage + unauthorizedAccessException.Message + " -> Retrying in about {0} milliseconds...", sleepTimeInMs)); 
     Thread.Sleep(sleepTimeInMs); 
    } 
    catch (Exception exception) 
    { 
     loggingMessage += "Failed: "; 
     IOLogger.LogError(loggingMessage + exception.Message); 
    } 
} 

Sen sleepTimeInMs ve/veya maxRetries etrafında oynayabilir. Bu değerleri seçtim çünkü ihtiyaç duyulan herhangi bir kullanımda yeterli görünüyorlardı.