Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Email scrip freezing unity

Discussion in 'Scripting' started by CubicPro, Aug 24, 2016.

  1. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    Hi, I have this script to send and email when the player press the button:

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using UnityEngine.UI;
    4. using System.Net;
    5. using System.Net.Mail;
    6. using System.Collections;
    7. using System.Net.Security;
    8. using System.Security.Cryptography.X509Certificates;
    9.  
    10.  
    11. public class SendEmail : MonoBehaviour {
    12.  
    13.     public bool EmailSent;
    14.     public GameObject SendingIcon;
    15.  
    16.  
    17.     public void SendEmailButton(){
    18.         SendingIcon.SetActive (true); // active a button showing the message sending email just for the player knows what happening
    19.         SendEmailF();
    20.     }
    21.  
    22.     public void SendEmailF(){
    23.         MailMessage mail = new MailMessage();
    24.  
    25.         mail.From = new MailAddress("xxxxxxxxxxx@gmail.com.br");
    26.         mail.To.Add("xxxxxxxx@gmail.com.br");
    27.         mail.Subject = "Player name ";
    28.         mail.Body = "test";  
    29.  
    30.  
    31.         SmtpClient smtpServer = new SmtpClient("smtp.gmail.com");
    32.         smtpServer.Port = 587;
    33.         smtpServer.EnableSsl = true;
    34.         smtpServer.Credentials = new System.Net.NetworkCredential("xxxxxxxxx@gmail.com.br", "xxxxxxxxxxx") as ICredentialsByHost;
    35.         ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){
    36.             return true;
    37.         };
    38.         SmtpDeliveryMethod.Network;
    39.         smtpServer.Send(mail);
    40.         Debug.Log("Sent");
    41.         EmailSent = true;
    42.         mail.Body = null;
    43.     }
    44.  
    45.     void Update(){
    46.  
    47.         if (EmailSent) {
    48.             SendingIcon.SetActive (false);
    49.             EmailSent = false;
    50.         }
    51.     }
    but when I press the button to send the email, unity freezes for exactly 25 seconds, and just works again when the email is sent..

    I want to know if there a way to make this process faster.. or if not, how I make to unity, or the finished app, don't freeze, because if need to take this time, the sending message will show in the screen until finish and the player will know..

    thanks!
     
    OdColmen likes this.
  2. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    I already make a new empty scene, put only the button and the script and this freeze too. don't know what to do.
     
  3. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    The function may be blocking the main thread. Try making it into a coroutine. You could try pausing execution from a debugger when it's freezing. Then you can find out which part is taking so long.
     
    CubicPro likes this.
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    CubicPro likes this.
  5. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    Hi, thanks for the reply, SendAsync do the trick and the unity don't freeze anymore, but a new problem shows up, I add a confirmation email in the script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using UnityEngine.UI;
    4. using System.Net;
    5. using System.Net.Mail;
    6. using System.Collections;
    7. using System.Net.Security;
    8. using System.Security.Cryptography.X509Certificates;
    9.  
    10.  
    11. public class SendEmail : MonoBehaviour {
    12.  
    13.     public bool EmailSent;
    14.     public GameObject SendingIcon;
    15.     public string playerEmail;
    16.  
    17.  
    18.     public void SendEmailButton(){
    19.         SendingIcon.SetActive (true); // active a button showing the message sending email just for the player knows what happening
    20.         SendEmailF();
    21.     }
    22.  
    23.     public void SendEmailF(){
    24.         MailMessage mail = new MailMessage();
    25.  
    26.         mail.From = new MailAddress("xxxxxxxxxxx@gmail.com.br");
    27.         mail.To.Add("xxxxxxxx@gmail.com.br");
    28.         mail.Subject = "Player name ";
    29.         mail.Body = "test";
    30.  
    31.  
    32.         SmtpClient smtpServer = new SmtpClient("smtp.gmail.com");
    33.         smtpServer.Port = 587;
    34.         smtpServer.EnableSsl = true;
    35.         smtpServer.Credentials = new System.Net.NetworkCredential("xxxxxxxxx@gmail.com.br", "xxxxxxxxxxx") as ICredentialsByHost;
    36.         ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){
    37.             return true;
    38.         };
    39.         SmtpDeliveryMethod.Network;
    40.         smtpServer.Send(mail);
    41.         Debug.Log("Request Sent");
    42.         StartCoroutine (SendConfirmationEmail());
    43.         mail.Body = null;
    44.     }
    45.  
    46.     public void SendEmailR(){
    47.         playerEmail = PlayerPrefs.GetString ("PlayerEmail");
    48.         MailMessage mail = new MailMessage();
    49.  
    50.         mail.From = new MailAddress("xxxxxxxxxxx@gmail.com.br");
    51.         mail.To.Add(playerEmail);
    52.         mail.Subject = "Player name ";
    53.         mail.Body = "Your Request has been receive";
    54.  
    55.  
    56.         SmtpClient smtpServer = new SmtpClient("smtp.gmail.com");
    57.         smtpServer.Port = 587;
    58.         smtpServer.EnableSsl = true;
    59.         smtpServer.Credentials = new System.Net.NetworkCredential("xxxxxxxxx@gmail.com.br", "xxxxxxxxxxx") as ICredentialsByHost;
    60.         ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){
    61.             return true;
    62.         };
    63.         SmtpDeliveryMethod.Network;
    64.         smtpServer.Send(mail);
    65.         Debug.Log("Confirmation Sent");
    66.         EmailSent = true;
    67.         mail.Body = null;
    68.     }
    69.  
    70.     IEnumerator SendConfirmationEmail(){
    71.         yield return new WaitForSeconds (3);
    72.         SendEmailR ();
    73.         StopAllCoroutines();
    74.     }
    75.  
    76.  
    77.     void Update(){
    78.  
    79.         if (EmailSent) {
    80.             SendingIcon.SetActive (false);
    81.             EmailSent = false;
    82.         }
    83.     }

    I receive in the console the Debug.Log from the 2 emails, but in my email box, I only receive the confirmation email.. I noticed that this happens after I put the SendAsync in the code, with Send unity freeze but send the 2 emails, with the SendAsync only the second email go.

    I tried put the coroutine like Boz0r say but do the same thing, only the second email go.. what I do?

    thanks a lot for the Help!!! :D
     
  6. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    If Helps, I was searching in the web and found a function called SendCompleted but don't understand how it works..
     
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Hmm, I'm still seeing Send rather than SendAsync in that code.

    But yeah, I would expect that the problem is that you're calling SendAsync again before the first one is done. You'll need to use something like SendCompleted to wait until the first send is fully complete, and then send the second one.
     
    CubicPro likes this.
  8. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    Hi Joe Strout,

    sorry for the send, I just copied the cody from above in the first post and replied to make the second part, I dont wanna to change all information I put in the unity like texts and emails again so I copied the first..

    But in unity I am using SendAsync, and make the SendComplete works but received this error:

    System.Net.Mail.SmtpException: Message could not be sent. ---> System.ArgumentNullException: Argument cannot be null.
    Parameter name: s
    at System.Text.Encoding.GetBytes (System.String s) [0x00006] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Text/Encoding.cs:268
    at System.Net.Mail.SmtpClient.EncodeBody (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0
    at System.Net.Mail.SmtpClient.SendSimpleBody (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0
    at System.Net.Mail.SmtpClient.SendWithoutAttachments (System.Net.Mail.MailMessage message, System.String boundary, Boolean attachmentExists) [0x00000] in <filename unknown>:0
    at System.Net.Mail.SmtpClient.SendCore (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0
    at System.Net.Mail.SmtpClient.SendInternal (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0
    at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0
    --- End of inner exception stack trace ---
    at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0
    at System.Net.Mail.SmtpClient+<SendAsync>c__AnonStorey5.<>m__5 (System.Object o, System.ComponentModel.DoWorkEventArgs ea) [0x00000] in <filename unknown>:0
    UnityEngine.MonoBehaviour:print(Object)
    SendEmail:SendCompleted(Object, AsyncCompletedEventArgs) (at Assets/EUROSILICONE/scripts/SendEmail.cs:90)
    System.ComponentModel.BackgroundWorker:<CompleteWorker>m__1(Object)


    I saw the explanation about the Send Complete here:

    https://msdn.microsoft.com/pt-br/library/system.net.mail.smtpclient.sendcompleted(v=vs.110).aspx

    and made this:

    Code (CSharp):
    1. public void SendEmailR(){
    2.         string usertoken = "Request Email";
    3.         MailMessage mail = new MailMessage();
    4.  
    5.         mail.From = new MailAddress("xxxxxxxxxxxx@gmail.com");
    6.         mail.To.Add("xxxxxxxxxx@gmail.com");
    7.         mail.Subject = "Player Name;
    8.        mail.Body = MailBody;    
    9.  
    10.  
    11.        SmtpClient smtpServer = new SmtpClient("smtp.gmail.com",587);
    12.        // smtpServer.Port = 587;
    13.        smtpServer.Credentials = new System.Net.NetworkCredential("pedidoviaapp@admedic.com.br", "pedidoviaapp1234") as ICredentialsByHost;
    14.        //smtpServer.Credentials = CredentialCache.DefaultNetworkCredentials as ICredentialsByHost;
    15.        smtpServer.EnableSsl = true;
    16.        smtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;
    17.        ServicePointManager.ServerCertificateValidationCallback =
    18.            delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    19.        { return true; };
    20.        smtpServer.SendAsync (mail, usertoken);
    21.        smtpServer.SendCompleted += new SendCompletedEventHandler (SendCompleted);
    22.        mail.Body = null;
    23.    }
    24.  
    25. void SendCompleted(object sender, AsyncCompletedEventArgs e){
    26.        String token = (string)e.UserState;
    27.  
    28.        if (e.Error != null) {
    29.            print (e.Error.ToString ());
    30.        } else {
    31.            print("Request Sent");
    32.            StartCoroutine (SendConfirmationEmail ());
    33.        }
    34.    }
    but the error for me appears be in something inside of unity.. and dont know what to do..

    thanks for the reply and help!
     
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It's not within Unity, it's within SmtpClient (which is part of the .NET/Mono framework). And the error suggests that something is null that shouldn't be. I can't tell exactly what, because that still isn't your real code above. :)
     
    CubicPro likes this.
  10. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    Hi Joe Strout,

    thanks again for the reply, I figured out, and make work.. the line that making the problem is
    Code (CSharp):
    1. mail.body = null;
    in the final part of the first email function.. but that make me a new problem, how I will empty the information that I put in the email to send a new without the information that I send previously?
     
  11. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    Here is the code working for anyone who need :
    Code (CSharp):
    1. public void SendEmailR(){
    2.         string usertoken = "Request Email";
    3.         MailMessage mail = new MailMessage();
    4.  
    5.  
    6.         mail.From = new MailAddress("xxxxxxxxxx@gmail.com");
    7.         mail.To.Add("xxxxxxxxxx@gmail.com");
    8.         mail.Subject = "Request";
    9.         mail.Body = "this is the request email"
    10.  
    11.  
    12.         SmtpClient smtpServer = new SmtpClient("smtp.gmail.com",587);
    13.         // smtpServer.Port = 587;
    14.         smtpServer.Credentials = new System.Net.NetworkCredential("xxxxxxxxxx@gmail.com", "xxxxxxxxxxxxxxxxxx") as ICredentialsByHost;
    15.         //smtpServer.Credentials = CredentialCache.DefaultNetworkCredentials as ICredentialsByHost;
    16.         smtpServer.EnableSsl = true;
    17.         smtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;
    18.         ServicePointManager.ServerCertificateValidationCallback =
    19.             delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    20.         { return true; };
    21.         smtpServer.SendAsync (mail, usertoken);
    22.         smtpServer.SendCompleted += SmtpServer_SendCompleted;
    23.         Debug.Log("Request Sent");
    24.     }
    25.  
    26.     void SmtpServer_SendCompleted (object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    27.     {
    28.         SendEmailC ();
    29.     }
    30.  
    31.     public void SendEmailC(){
    32.         string usertoken = "Confirmation Email";
    33.         MailMessage mail = new MailMessage();
    34.  
    35.  
    36.         mail.From = new MailAddress("xxxxxxxxxx@gmail.com");
    37.         mail.To.Add("xxxxxxxxxx@gmail.com");
    38.         mail.Subject = "Resquest receive";
    39.         mail.Body = "Your request has been receive";
    40.        
    41.  
    42.         SmtpClient smtpServer = new SmtpClient("smtp.gmail.com",587);
    43.         // smtpServer.Port = 587;
    44.         smtpServer.Credentials = new System.Net.NetworkCredential("xxxxxxxxxx@gmail.com", "xxxxxxxxxxxxxxxxx") as ICredentialsByHost;
    45.         //smtpServer.Credentials = CredentialCache.DefaultNetworkCredentials as ICredentialsByHost;
    46.         smtpServer.EnableSsl = true;
    47.         smtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;
    48.         ServicePointManager.ServerCertificateValidationCallback =
    49.             delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    50.         { return true; };
    51.         smtpServer.SendAsync (mail, usertoken);
    52.         Debug.Log("Confirmation Sent");
    53.     }
     
  12. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Code (csharp):
    1. mail.Body = "";
    2. mail.Body = String.Empty;
    will both create an empty string, without the string variable being null.

    If at some point you need to check a string for null or empty, there's a nice little shortcut in String.IsNullOrEmpty(mail.Body) as well.
     
    CubicPro likes this.
  13. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Or just assign the new body. You don't need to clear out the old value before assigning a new value; just assign the new value.
     
    CubicPro likes this.
  14. CubicPro

    CubicPro

    Joined:
    Jan 17, 2015
    Posts:
    70
    Hi, thanks for the reply and all the help!!

    I find my error, I was setting the the mail.body in other script, and making the SendEmail script get the string from the other script, that why the email don't clean up.. now I add a function that clean the string in the other scrip when the email was sent..

    thanks a lot for all the time and help!