-2

C# と Arduino で Gmail 通知機能を作成しています。
このコードは、メールを受信したかどうかをチェックし、受信した場合は「m」をシリアルに送信します。
かなりうまくいっているようですが、問題はこのメッセージを一度受け取った後です。

未読メール: 0

このメッセージは画面に表示され続けます。

「COM5」ポートへのアクセスが拒否されました。
「COM5」ポートへのアクセスが拒否されました。
...

これは明らかに、コードの最初の試行の後、COM5 へのアクセスが拒否されることを意味します。
port.Close(); を追加しようとしました。私のコードに、しかしその後、コードは 2 回目の試行後にループしません。
ちょっとここで立ち往生。
私のコードの問題は何ですか?
同様の質問がウェブ上にあるようです(ポート「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。ポートを 1 回だけ (ループの外側で) 開き、1 回だけ閉じてみてください (完了時または例外がスローされたとき)。

于 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 に答える