18

これはかなり簡単なようです。ASP.NET アプリケーションから電子メールを送信する必要があります。奇妙なエラーが発生せず、CPU 使用率が上限を超えることなく、一貫してこれを行う必要があります。私は大量の電子メールについて話しているのではなく、時折の電子メールについて話している.

System.Net.Mailひどく壊れているようです。SmtpClient は Quit コマンドを発行しないため (Microsoft(R) が仕様に従うことに関心がないためかもしれません)、接続は開いたままになります。したがって、その接続が最終的に閉じる前に誰かが電子メールを送信しようとすると、開いている接続が多すぎるというエラーを SMTP サーバーから受け取る可能性があります。これは、Microsoft(R) が修正にまったく関心がないバグです。ここを参照してください:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=146711

また、このコードを使用してこの問題を解決することをお勧めします。

smtpClient.ServicePoint.MaxIdleTime = 1;
smtpClient.ServicePoint.ConnectionLimit = 1;

わかりました、はい、接続が開いたままになるという問題を「解決」します。ただし、これは一貫して、必要に応じてサーバーで試してみると、プロセス (この場合は w3wp.exe) が実行されている CPU がジャンプし、アプリケーション プールがリサイクルされるまで 100% のままになります。何らかの理由で、mscorwks.dll!CreateApplicationContext を実行するスレッドが原因です。

これには、持続的な 100% の CPU 使用率に眉をひそめる Web ホストで実行している場合、アプリケーション プールが無効になるという非常に良い副作用があります。したがって、これは一部の人が示唆するほど簡単ではありません。

だから私の質問は何をすべきか?私がしなければならないことはとても簡単です。ただし、「開いている接続が多すぎます」というエラーは受け入れられず、CPU 使用率も 100% ではありません。サード パーティのコンポーネントを購入したくないのは、安いからではありませんが、シンプルな SMTP 機能に 100 ドルから 300 ドルを支払う必要があるとは思えないほど、十分な数のコンポーネントと MSDN サブスクリプションを購入しています。

MaxIdleTime を高く設定すると役立つことがあると読みましたが、それには懐疑的です。Microsoft が SMTP 仕様に準拠したくないという理由だけで、アプリ プールが無効になる危険を冒したくありません。

編集: quiksoft.com コンポーネントを見ましたが、SMTP 認証をサポートしておらず、500 ドルかかります。この問題には解決策が必要です。

4

7 に答える 7

30

.NET 4.0 では、SmtpClient が使い捨てになりました。SMTP QUIT コマンドは、using ブロックで使用された場合など、破棄時に発行されます。

于 2010-11-29T18:40:42.733 に答える
22

説明されている設定で、同じ CPU 使用率の問題に直面しました。問題の原因を特定するために、Microsoft にチケットをオープンすることになりました。CPU 使用率の問題は ServicePoint クラスにあります。ServicePoint クラスの内部には、(MaxIdleTime/2) ミリ秒ごとに実行されるタイマーがあります。問題が見えますか?MaxIdleTime 値を 2 に変更すると、CPU 使用率が通常のレベルに低下します。

于 2009-07-27T21:26:06.647 に答える
2

hMailserverを使用して大きな成功を収めました。設定に慣れるまでに時間がかかる場合がありますが、優れた無料のメール サーバー製品です。

独自のコードを作成したい場合 (私が数年前に CDONTS で苦労していたときに行いました)、以下のコードから始めて、心ゆくまでカスタマイズできます。TcpClient を使用して、メールサーバーへの TCP 接続を直接作成します。非常に多くの確立されたデバッグ済みのソリューションがある場合、これをお勧めするわけではありませんが、プレハブの MS メール コンポーネントで問題がどこにあったかをデバッグおよび特定するのに非常に役立つことがわかりました。

    private void Send_Email() 
    {
        #region Email Sending Function
        string strMail = "";

        try 
        {
            // See RFC821 http://www.faqs.org/rfcs/rfc821.html for more specs
            // TcpClient is an abstraction of a TCP Socket connection
            TcpClient myTCP = new TcpClient();

            // Connect to the mail server's port 25
            myTCP.Connect(mailserver, 25);

            // Open a network stream which sends data to/from the TcpClient's socket
            System.Net.Sockets.NetworkStream ns = myTCP.GetStream();

            // The data to send to the mail server, basically a raw SMTP mail message
            strMail = "HELO\n";
            strMail += "MAIL FROM:from@address.com\n";
            strMail += "RCPT TO:" + recipient + "\n";
            strMail += "DATA\n";
            strMail += "Subject: mySubject\n";
            strMail += "To:" + recipient + "\n";
            strMail += "From: \"From Real Name\" <from@address.com>\n";
            strMail += "\n";
            strMail += " ---------------------------------------\n";
            strMail += "Name:     " + txtName.Text + "\n";
            strMail += "Address1: " + txtAddress1.Text + "\n";
            strMail += "Address2: " + txtAddress2.Text + "\n";
            strMail += "City:     " + txtCity.Text + "\n";
            strMail += "State:    " + txtState.Text + "\n";
            strMail += "Zip:      " + txtZip.Text + "\n";
            strMail += "Email:    " + txtEmail.Text + "\n";
            strMail += "Dealer:   " + txtDealer.Text + "\n";
            strMail += " ---------------------------------------\n";
            strMail += "THIS IS AN AUTOMATED EMAIL SYSTEM. DO NOT REPLY TO THIS ADDRESS.\n";
            strMail += "\n.\n";

            // Defines encoding of string into Bytes (network stream needs
            // an array of bytes to send -- can't send strings)
            ASCIIEncoding AE = new ASCIIEncoding();
            byte[] ByteArray = AE.GetBytes(strMail);

            // send the byte-encoded string to the networkstream -> mail server:25
            ns.Write(ByteArray, 0, ByteArray.Length);

            //ns.Read(ByteArray, 0, ByteArray.Length);
            //lblStatus.Text = ByteArray.ToString();

            // close the network stream
            ns.Close();

            // close the TCP connection
            myTCP.Close();
        }
        catch(Exception ex) 
        {
            throw new Exception("Couldn't send email: <p>" + ex.Message);
        }

        #endregion

    }
于 2010-11-04T06:25:42.330 に答える
2

私は常に Quiksoft の EasyMail .NET コンポーネントをまったく問題なく使用してきました。

製品ホームページ: http://www.quiksoft.com/emdotnet/

電子メールの送信のみが必要な場合は、コンポーネントの無料バージョンもあります。

http://www.quiksoft.com/freesmtp/

于 2009-05-30T18:13:19.753 に答える
1

これまでのところ特に問題はありませんが、CDOSYS のラッパーであるSystem.Net.Mail古い API をいつでも使用できます。System.Web.Mail

于 2009-05-30T18:12:16.450 に答える
1

過去にQuicksoftを使用しましたが、不満はありません。他に試してみることができるのは、ネットワークを使用して送信する代わりにピックアップ フォルダーを使用するように SMTP 構成を切り替えることです。これにより、「QUIT が送信されない」問題を回避できます。

于 2009-05-31T13:04:02.207 に答える
-1

私はほとんどのメールを Sproc を使って送信しています。ファイルを添付することもできます。

CREATE PROCEDURE [dbo].[sendMail_With_CDOMessage]  
    @to VARCHAR(64),
    @CC VARCHAR(1024)='',
    @BCC VARCHAR(1024)='',
    @subject VARCHAR(500)='',
    @body VARCHAR(8000)='' 、
    @from VARCHAR(64),
    @ファイル名 VARCHAR(255)='',
    @プライオリティ INT = 0
なので  
始める  
    NOCOUNTをオンに設定  

    宣言する  
        @ハンドルINT、  
        @return INT,  
        @s VARCHAR(64),  
        @sc VARCHAR(1024),  
        @up CHAR(27),   
        @server VARCHAR(255)  

    SET @s = '"http://schemas.microsoft.com/cdo/configuration/'  

    選択する  
        @s = 'Configuration.Fields(' + @s,  
        @up = '構成.フィールド.更新',
        @server = 'smtp.yourdomain.com'



    EXEC @return = sp_OACreate 'CDO.Message', @handle OUT  
    SET @sc = @s + 'sendusing").Value'  
    EXEC @return = sp_OASetProperty @handle, @sc, '2'  
    SET @sc = @s + 'smtpserver").Value'  
    EXEC @return = sp_OASetProperty @handle、@sc、@server  
    EXEC @return = sp_OAMethod @handle、@up、NULL  
    EXEC @return = sp_OASetProperty @handle, 'To', @to  
    EXEC @return = sp_OASetProperty @handle, 'CC', @CC
    EXEC @return = sp_OASetProperty @handle, 'BCC', @BCC
    EXEC @return = sp_OASetProperty @handle, 'From', @from  
    EXEC @return = sp_OASetProperty @handle, 'Subject', @subject  
    EXEC @return = sp_OASetProperty @handle, 'HTMLBody', @body    
    EXEC @return = sp_OASetProperty @handle, 'Priority', 'cdoHigh'  

    IF @filename IS NOT NULL  
        EXEC @return = sp_OAMethod @handle, 'AddAttachment', NULL, @filename  

    EXEC @return = sp_OAMethod @handle, 'Send', NULL  
    IF @リターン 0  
    始める  
        PRINT 「メールが失敗しました。」  
        IF @from IS NULL  
            PRINT '送信元アドレス未定義.'  
        そうしないと  
            PRINT 'サーバーが有効であることを確認してください。
    終わり
    そうしないと  
        PRINT 「メールを送信しました。」  

    EXEC @return = sp_OADestroy @ハンドル  
終わり  

于 2009-06-01T18:41:52.533 に答える