2012-12-08 145 views
-2

我正在用C#和Arduino製作Gmail通知器。
代碼檢查它是否收到郵件併發送'm'到串行如果是。
它似乎工作得很好,但問題是當我得到這個消息後,COM5端口訪問在C#中被拒絕gmail通知器

未讀郵件:0

此消息保持打印屏幕上:

「COM5」端口訪問被拒絕。
「COM5」端口訪問被拒絕。
...

這顯然意味着代碼的第一次試用後拒絕訪問COM5。
我試着添加port.Close();到我的代碼,但然後代碼不會在第二次審判後循環。
有點卡在這裏。
什麼似乎是我的代碼的問題?
類似的問題似乎在網上(Access to the port 'COM5' is denied),但我真的不明白我如何「包裝使用串行端口」。
謝謝!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO.Ports; 
using System.Threading; 
using System.Net; 
using System.Xml; 

namespace GMailNotifier 
{ 
    class GMail 
    { 
     public static void Main(string[] args) 
     { 
      while (true) 
      { 
       try 
       { 
        SerialPort port = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One); 
        port.Open(); 

        string Unreadz = "0"; 
        Unreadz = CheckMail(); 
        Console.WriteLine("Unread Mails: " + Unreadz); 

        if (!Unreadz.Equals("0")) port.Write("m"); 
        else port.Write("n"); 
       }catch (Exception ee){ Console.WriteLine(ee.Message); 
       }finally { System.Threading.Thread.Sleep(1000); } 
      } 
     } 
    private static string CheckMail() { 
     string result = "0"; 

     try { 
     var url = @"https://gmail.google.com/gmail/feed/atom"; 
     var USER = "USER"; 
     var PASS = "PASS"; 

     var encoded = TextToBase64(USER + ":" + PASS); 

     var myWebRequest = HttpWebRequest.Create(url); 
     myWebRequest.Method = "POST"; 
     myWebRequest.ContentLength = 0; 
     myWebRequest.Headers.Add("Authorization", "Basic " + encoded); 

     var response = myWebRequest.GetResponse(); 
     var stream = response.GetResponseStream(); 

     XmlReader reader = XmlReader.Create(stream); 
     while (reader.Read()) 
      if (reader.NodeType == XmlNodeType.Element) 
      if (reader.Name == "fullcount") { 
       result = reader.ReadElementContentAsString(); 
       return result; 
      } 
     } catch (Exception ee) { Console.WriteLine(ee.Message); } 
     return result; 
    } 
    public static string TextToBase64(string sAscii){ 
     System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); 
     byte[] bytes = encoding.GetBytes(sAscii); 
     return System.Convert.ToBase64String(bytes, 0, bytes.Length); 
    } 
    } 
} 

回答

0

我真的不明白我怎麼能「包使用的SerialPort的」。

它的意思是做這樣的事情:

using (SerialPort port = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One)) 
{ 
    port.Open(); 

    string Unreadz = "0"; 
    Unreadz = CheckMail(); 
    Console.WriteLine("Unread Mails: " + Unreadz); 

    if (!Unreadz.Equals("0")) port.Write("m"); 
    else port.Write("n"); 
} 

using聲明將確保SerialPort.Dispose方法被調用,以釋放端口您使用完之後。如果您第一次沒有釋放它,那麼硬件仍然很忙,您將無法再次打開它(直到它稍後被垃圾回收)。

+0

謝謝@ChrisW。現在我用'using'語句包裝它,但問題是'未讀郵件:0'信息只出現兩次,然後停止出現。我希望代碼以1秒的間隔(這是通過「睡眠」完成的)持續發送消息。什麼似乎是問題? –

+0

@KiHyeokJeong使用調試器,或者將「日誌」消息插入源代碼,找出停止的地方。例如,如果您未收到網絡請求的回覆,該怎麼辦?默認的HttpWebRequest.Timeout值是100秒。 – ChrisW

1

您不應該打開while中的端口。嘗試只打開一次端口(在循環之外)並僅關閉一次(當完成或拋出異常時)。