Thursday, September 10, 2015

Explicitly freeing memory in c#

Recently I wrote a program which loads some CSV files in to DataTables and do some processing. These files are in large size and have nearly 1 million rows. When I load first file in to data table it works fine. But then I load the second file I get a “Out of Memory exception” even though first I make the previously loaded datatable to null. After searching for hours I found the following solution which solved my issue.

  1. var sourceDataTable = DataParserHelper.GetDataTableFromCsv(@"F:\FileSplitter\Data\5263\property_finance.csv");
  2.         
  3.          sourceDataTable.Clear();
  4.          sourceDataTable.Dispose();
  5.          sourceDataTable = null;            
  6.          GC.Collect();
  7.          GC.WaitForFullGCComplete();
  8.          GC.WaitForPendingFinalizers();

 

if you make the datatable null what happens is it frees the Datatable from the rows and columns. But actually those rows and columns retained in the memory and those are not ready for the garbage collector. But when you call Clear() all the memory will be cleared.

 

Hope this helps.

 

Happy Coding !!!

Monday, September 7, 2015

Sending Emails using SendGrid in C#.net

SendGrid has been built from the ground up as an API company. It is built to serve developers and make it easy to send email no matter your environment. You can send email over SMTP or HTTP, and even use one of it’s official client libraries. In just a few minutes, you can send your first email and millions more. It has different pricing plans for you , so you can select as you want. There is a free plan to which you can send up to 12,000 emails per month for free.

For more details about pricing visit here

1. Create an account in SendGrid

2. Create a Console Application and add the following nuget package.

SendGrid 5.1.0

3. Create a email template in SendGrid.

4. In the following example I’m loading some user information saved in a CSV file and then send password information for those users. Following is the template I have created for that in SendGrid. In the template I have used “{{}}” to specify the tags. You can use what ever the tab you want but make sure you use the same tag when you send the email request to sendgrid

Email Template
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. </head>
  6. <body>
  7. <p>&lt;%body%&gt;</p>
  8.  
  9. <p>Dear {{FirstName}}</p>
  10.  
  11. <p>You have been granted access to  raise online Facilities Service Requests.</p>
  12.  
  13. <p>Your user id is : {{UserName}}</p>
  14.  
  15. <p>Your password is:&nbsp; {{Password}}</p>
  16.  
  17. <p>Thanks</p>
  18.  
  19. </body>
  20. </html>
  21. <title></title>

5. Create a User Model class

  1. public class User
  2.     {
  3.         public string UserName { get; set; }
  4.         public string Password { get; set; }
  5.         public string FirstName { get; set; }
  6.         public string LastName { get; set; }
  7.         public string Email { get; set; }
  8.     }

6. Load CSV file to DataTable

  1. public static System.Data.DataTable LoadContent(string filePath)
  2.       {
  3.           StreamReader sr = new StreamReader(filePath);
  4.           string[] headers = sr.ReadLine().Split(',');
  5.           DataTable dt = new DataTable();
  6.           foreach (string header in headers)
  7.           {
  8.               dt.Columns.Add(header);
  9.           }
  10.           while (!sr.EndOfStream)
  11.           {
  12.               string[] rows = sr.ReadLine().Split(',');
  13.               DataRow dr = dt.NewRow();
  14.               for (int i = 0; i < headers.Length; i++)
  15.               {
  16.                   dr[i] = rows[i];
  17.               }
  18.               dt.Rows.Add(dr);
  19.           }
  20.           return dt;
  21.       }

7. Load User List using the DataTable

  1.  public static List<User> GetUserList(DataTable content)
  2.       {
  3.           List<User> users = new List<User>();
  4.  
  5.             foreach (DataRowrow in content.Rows)
  6.           {
  7.               User user = new User();
  8.               user.FirstName = row["FirstName"].ToString();
  9.               user.LastName = row["LastName"].ToString();
  10.               user.UserName = row["UserName"].ToString();
  11.               user.Password = row["Password"].ToString();
  12.               user.Email = row["Email"].ToString();
  13.               users.Add(user);
  14.           }
  15.  
  16.           return users;
  17.       }

8. Send Email to users using SendGrid

  1. public static void SendEmail(string filePath)
  2.       {
  3.           DataTable content = LoadContent(filePath);
  4.  
  5.           List<User> users = GetUserList(content);
  6.  
  7.           foreach (User user in users)
  8.           {
  9.               string xmstpapiJson = GetMessageHeader(user);
  10.  
  11.               SendGridMessage sendGridMessage = new SendGridMessage();
  12.               sendGridMessage.From = new MailAddress(fromAddress, fromName);
  13.               sendGridMessage.AddTo(user.Email);
  14.               sendGridMessage.Subject = "New Registration";
  15.               sendGridMessage.Headers.Add("X-SMTPAPI", xmstpapiJson);
  16.               sendGridMessage.Html = string.Format(" ");
  17.  
  18.  
  19.               var userName = sendGridUserName;
  20.               var password = SendGridPassword;
  21.               var credentials = new NetworkCredential(userName, password);
  22.               var transportWeb = new Web(credentials);
  23.  
  24.               transportWeb.Deliver(sendGridMessage);
  25.               Console.WriteLine("Email Sent to:"+user.Email);
  26.            
  27.               
  28.           }
  29.  
  30.           Console.WriteLine(string.Format("{0} Emails Sent", users.Count()));
  31.           Console.ReadLine();
  32.           
  33.       }
  34.  
  35.       private static string GetMessageHeader(User user)
  36.       {
  37.           var header = new Header();
  38.  
  39.           header.AddSubstitution("{{FirstName}}", new List<string> { user.FirstName });
  40.           header.AddSubstitution("{{LastName}}", new List<string> { user.LastName });
  41.           header.AddSubstitution("{{UserName}}", new List<string> { user.UserName });
  42.           header.AddSubstitution("{{Password}}", new List<string> { user.Password });
  43.           header.AddFilterSetting("templates", new List<string> { "enabled" }, "1");
  44.           header.AddFilterSetting("templates", new List<string> { "template_id" }, "67d23037-08bc-445a-bda1-903f6af65b67");
  45.           return header.JsonString();
  46.       }

 

Hope This Helps.

 

Happy Coding !!!

Point in Time Restore in Azure SQL Database

With new Basic, Standard and Premium Service Tiers , you get the new improved facility of “Point in Time Restore”. Which is, it provides you zero-cost automatic backup system. You only incur additional cost if you use the restore capability. The new database created by restore is charged at normal database rates. Together, the automated backup system and point-in-time restore provide a zero-cost, zero-admin way to protect databases from accidental corruption or deletion, whatever the cause.

Period that backups retain will based on the service tier.

Basic Tier :- 7 Days

Standard Tier :- 14 Days

Premium Tier :- 35 Days

 

Restoring a Live Database to a Point in Time

Using Azure management portal you can easily. Go to the Database which you want to restore. Then Click on the “Restore” Button in the bottom bar.

image

You will be prompted for a new database name and offered a slider control to pick the restore point within the retention period. Alternatively, you can manually enter the date and time to the nearest minute. Once you confirm the action, the database will be restored.

image

 

After you confirmed your new database will be create in with the given name in the same database sever.The time taken to restore the database depends on many factors, including the size of the database, the time point selected, and the amount of activity that needs to be replayed to reconstruct the state at the selected point. For a very large and/or active database restore may take several hours.

 

Restoring a Deleted Database

If you want to restore a deleted database which is using Basic, Standard or Premium service tier , You are given the facility of restoring it to the point which it has been deleted. To restore go to SQL databases tab in Management portal and go to deleted databases. There you can see a list of databases which has been deleted.

image

Select the database you want to restore then click on the restore button at the bottom. Then you will get the following window which you can type a name for the database and restore the backup for a new database

image

 

Hope this helps.

Calling Async Call from Main()

This is a small code which shows different ways of calling an async method inside Main

Following is my sample method.

  1. public async Task<int>SampleMethod()
  2.     {
  3.         await Task.Delay(5000);
  4.         int answer = 21 * 2;
  5.         return answer;
  6.     }

 

1. Using  GetAwaiter()

 

  1. static void Main(string[] args)
  2.     {
  3.         SampleMethod().GetAwaiter().OnCompleted(() =>
  4. {
  5.     Console.WriteLine("finished");
  6. });
  7.         Console.ReadKey();
  8.     }

 

2. Using  Wait()

  1. static void Main(string[] args)
  2.     {
  3.         SampleMethod().Wait();
  4.     }

 

Hope this helps,