-2

我正在用 C# 和 Arduino 制作一个 Gmail 通知器。
该代码检查它是否收到邮件,如果收到,则将“m”发送到串口。
它似乎工作得很好,但问题是在我收到此消息后,

未读邮件:0

此消息不断打印在屏幕上:

'COM5' 端口访问被拒绝。
'COM5' 端口访问被拒绝。
...

这显然意味着在代码第一次试用后拒绝访问 COM5。
我试图添加 port.Close(); 到我的代码,但是在第二次试用后代码不会循环。
有点卡在这里。
我的代码似乎有什么问题?
类似的问题似乎在网络上(拒绝访问端口'COM5'),但我真的不明白如何“包装使用 SerialPort”。
谢谢!

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);
    }
  }
}
4

2 回答 2

1

您不应该在while. 尝试只打开一次端口(在循环之外)并只关闭一次(完成或抛出异常时)。

于 2012-12-08T09:32:57.437 回答
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 方法,以便在您使用完毕后释放端口。如果你第一次之后不释放它,那么硬件仍然很忙,你将无法再次打开它(直到它稍后被垃圾收集)。

于 2012-12-08T09:31:32.650 回答