Code Snippets Series – C#

8 minute read

1.Test Task Async DeadLocks

Demo Code (I am using winform app to demonstrate deadlocks which also happens on asp.net, but Console app don’t have such problem, even without calling Task.ConfigureAwait(false),codes that being ‘await’ will executed in new thread)

different between Task and Thread:

a.Task has return value (**Task.Result / **Task.GetAwaiter().GetResult())

b.Task run on created (Run/StartNew), Thread need Start after New

c.Task accept delegate/lamda, Thread accept object

d.Task can catch exception(after call **Task.Wait() / **Task.Result), Thread can not

Task.Run vs Task.Factory.StartNew

Task.Run Etiquette Examples: Don’t Use Task.Run in the Implementation

2.async await

Async Return Types

.Result and await block main Thread, ContinueWith doesn’t

await Task vs (Task<T> AsyncMethod).Result

async Task VS async Void VS async Task<T>

A Tour of Task, Part 6: Results In short, await should be your go-to option for retrieving task results. The vast majority of the time, await should be used instead of Wait, Result, Exception, or GetAwaiter().GetResult(). Await on a completed task same as task.Result?

warning: warning CS1998: This async method lacks ‘await’ operators and will run synchronously. Consider using the ‘await’ operator to await non-blocking API calls, or ‘await Task.Run(…)’ to do CPU-bound work on a background thread.

http://stackoverflow.com/questions/13243975/suppress-warning-cs1998-this-async-method-lacks-await

Error: An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async=”true” %>.

http://stackoverflow.com/questions/13647346/calling-async-method-in-controller

Error: DeadLocks


Don’t Block on Async Code: from http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

// My "library" method.
public static async Task<JObject> GetJsonAsync(Uri uri)
{
using (var client = new HttpClient())
{
var jsonString = await client.GetStringAsync(uri);
return JObject.Parse(jsonString);
}
}
// My "top-level" method.
public void Button1_Click(...)
{
var jsonTask = GetJsonAsync(...);
textBox1.Text = jsonTask.Result;
}

The top-level method calls GetJsonAsync (within the UI/ASP.NET context). GetJsonAsync starts the REST request by calling HttpClient.GetStringAsync (still within the context). GetStringAsync returns an uncompleted Task, indicating the REST request is not complete. GetJsonAsync awaits the Task returned by GetStringAsync. The context is captured and will be used to continue running the GetJsonAsync method later. GetJsonAsync returns an uncompleted Task, indicating that the GetJsonAsync method is not complete. The top-level method synchronously blocks on the Task returned by GetJsonAsync. This blocks the context thread. … Eventually, the REST request will complete. This completes the Task that was returned by GetStringAsync. The continuation for GetJsonAsync is now ready to run, and it waits for the context to be available so it can execute in the context. Deadlock. The top-level method is blocking the context thread, waiting for GetJsonAsync to complete, and GetJsonAsync is waiting for the context to be free so it can complete.

Preventing the Deadlock

There are two best practices (both covered in my intro post) that avoid this situation:

In your “library” async methods, use ConfigureAwait(false) wherever possible. Don’t block on Tasks; use async all the way down.

Consider the first best practice. The new “library” method looks like this:

public static async Task<JObject> GetJsonAsync(Uri uri)
{
using (var client = new HttpClient())
{
var jsonString = await client.GetStringAsync(uri).ConfigureAwait(false);
return JObject.Parse(jsonString);
}
}

This changes the continuation behavior of GetJsonAsync so that it does not resume on the context. Instead, GetJsonAsync will resume on a thread pool thread. This enables GetJsonAsync to complete the Task it returned without having to re-enter the context.

Consider the second best practice. The new “top-level” methods look like this:

public async void Button1_Click(...)
{
var json = await GetJsonAsync(...);
textBox1.Text = json;
}

public class MyController : ApiController
{
public async Task<string> Get()
{
var json = await GetJsonAsync(...);
return json.ToString();
}
}

This changes the blocking behavior of the top-level methods so that the context is never actually blocked; all “waits” are “asynchronous waits”.

Note: It is best to apply both best practices. Either one will prevent the deadlock, but both must be applied to achieve maximum performance and responsiveness.


Calling async method synchronously

void Func(){

Task<string> sCode = Task.Run(async () =>
{
string msg =await GenerateCodeAsync();
return msg;
});

}

3.Threading.Timer run Async Task

Sometimes you may encounter such a requirement that you have a timer, and you have to do a async operation inside timer’s callback which is a sync method.

(in Java they have TimerTask, but seems in C# we don’t have the equivalent class)

a.try Nito.AsyncEx - https://github.com/StephenCleary/AsyncEx

How to call asynchronous method from synchronous method in C#?

Explicitly use a Func for asynchronous lambda function when Action overload is available b.Task based timer implement:

Is there a Task based replacement for System.Threading.Timer?

How to implement Task Async for a timer in C#? c.I found this alternative ‘solution’, but this approach is proved not reliable.

var t = new System.Threading.Timer(async (object state) =>
{
await aysncOperation();
Console.WriteLine("Tmr Callback on: " + Thread.CurrentThread.ManagedThreadId);
});

here is why this approach can not work as we expect: Potential pitfalls to avoid when passing around async lambdas

references:

All about .NET Timers - A Comparison

MSDN:Asynchronous Programming with Async and Await (C# and Visual Basic)

Best Practices in Asynchronous Programming

Task-based Asynchronous Pattern

async & await 的前世今生

走进异步世界-犯傻也值得分享:ConfigureAwait(false)使用经验分享

C#中async编程完全代替了Task了吗

System.Timers.Timer “single-threaded” usage

System.Timers.Timer t;
 
void StartTimer()  {
  t = new System.Timers.Timer();
  t.Interval = 500;
  t.AutoReset = false;
  t.Elapsed += TimerProc;
  t.Enabled = true;
}
 
void TimerProc(object sender, System.Timers.ElapsedEventArgs e) {
  Task();
  t.Enabled = true;
}
 
void Task() {
}
https://www.codeproject.com/Questions/405564/Syste-Timers-Timer-single-threaded-usage

4. k__backingfield

Use DataContract DataMember, add reference System.Runtime.Serialization

5.there is already datareader associated with this command

http://devproconnections.com/development/solving-net-scalability-problem

6. Iterate Datetime beware of your datetime string, especially when the source is from excel

string dateStr="2016-01-01 11:59:59";

DateTime.ParseExtrat(dateStr,"yyyy-MM-dd",null)  ,  result is 2016-01-01 00:00:00 (12:00:00 am)

string dateStr="27/1/2011  11:27:19 AM";

DateTime.TryParseExact(***, "d/M/yyyy h:m:s tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)

string myValue = "12:00:00.000";

DateTime myDate = DateTime.ParseExact(myValue, "HH:mm:ss:fff");

C# DateTime Format: A Concise Explanation for Beginners

https://blog.udemy.com/c-sharp-datetime-format/

7.network folder

Unhandled Exception: System.ArgumentException: The UNC path should be of the form \server\share.

http://stackoverflow.com/questions/3567063/get-a-list-of-all-unc-shared-folders-on-a-local-network-server

//
// Enumerate shares on local computer
//
Console.WriteLine("\nShares on local computer:");
ShareCollection shi = ShareCollection.LocalShares;
if (shi != null)
{
foreach(Share si in shi)
{
Console.WriteLine("{0}: {1} [{2}]",
si.ShareType, si, si.Path);

// If this is a file-system share, try to
// list the first five subfolders.
// NB: If the share is on a removable device,
// you could get "Not ready" or "Access denied"
// exceptions.
if (si.IsFileSystem)
{
try
{
System.IO.DirectoryInfo d = si.Root;
System.IO.DirectoryInfo[] Flds = d.GetDirectories();
for (int i=0; i < Flds.Length && i < 5; i++) Console.WriteLine("\t{0} - {1}", i, Flds[i].FullName); Console.WriteLine(); } catch (Exception ex) { Console.WriteLine("\tError listing {0}:\n\t{1}\n", si, ex.Message); } } } } else Console.WriteLine("Unable to enumerate the local shares."); // // Resolve local paths to UNC paths. // Console.WriteLine("{0} = {1}", fileName, ShareCollection.PathToUnc(fileName));

8.Serialize De-serialize dynamic objects

Deserialize JSON into C# dynamic object?

http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object

Quick JSON Serialization/Deserialization in C#

9.Email attachment

https://gist.github.com/mvark/8c523eb47670c2fc8da4

10.OpenXML for excel

https://msdn.microsoft.com/en-us/library/bb448854.aspx

Stylizing https://blogs.msdn.microsoft.com/chrisquon/2009/11/30/stylizing-your-excel-worksheets-with-open-xml-2-0/

Set Column Width https://social.msdn.microsoft.com/Forums/en-US/37419b3b-fc97-47a4-a52f-fba62a9dcabf/how-to-open-an-existing-excel-worksheet-and-set-column-width-to-best-fit-using-openxml-sax-in-c-?forum=oxmlsdk

Open XML SDK: get “Unreadable content” error when trying to populate more than 25 columns

http://stackoverflow.com/questions/14525573/open-xml-sdk-get-unreadable-content-error-when-trying-to-populate-more-than-2

11.Unable to find manifest signing certificate in the certificate store

http://stackoverflow.com/questions/11957295/unable-to-find-manifest-signing-certificate-in-the-certificate-store-even-wh

12. Reflection

public class ObjectB
{
public int Id { get; set; }
public string Name { get; set; }
}

public class ObjectA
{
public int Id { get; set; }
public string Name { get; set; }
public ObjectB Child { get; set; }
}

a. Grap a property of ObjectB obj.GetType().GetProperty(“Name”).GetValue(obj, null);

b. Sum Of a column of generic list by passing column name anonymously List list:list.Sum(x => x.GetType().GetProperty(columnName).GetValue(x, null)).ToString();

c. Get Property Value of Nested Classes

public static class ReflectionHelper
{
public static Object GetPropValue(this Object obj, String propName)
{
string[] nameParts = propName.Split('.');
if (nameParts.Length == 1)
{
return obj.GetType().GetProperty(propName).GetValue(obj, null);
}
foreach (String part in nameParts)
{
if (obj == null) { return null; }

Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }

obj = info.GetValue(obj, null);
}
return obj;
}
}

13. SMTP

Gmail

pro#1: unable to read data from the transport connection net_io_connectionclosed

change port 465 to 587, EnableSsl = true, The .NET SmtpClient only supports encryption via STARTTLS. If the EnableSsl flag is set, the server must respond to EHLO with a STARTTLS, otherwise it will throw an exception.

pro#2: he SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.

it may not be your code issue but high possibility is that your gmail account may encounter security blocking, simpliest way is to check whether you have rececived an email like this: then click ‘allowing access to less secure apps’

if still cannot , try this https://accounts.google.com/DisplayUnlockCaptcha, unlock it

see more at http://stackoverflow.com/questions/20906077/gmail-error-the-smtp-server-requires-a-secure-connection-or-the-client-was-not

14.Compile error

1.for xml/ config file, some times got “Severity Code Description Project File Line Suppression State Error Invalid token ‘Text’ at root level of document”

right click- properties - Build Action - choose None.

2.Parser Error Message: Only one <configSections> element allowed per config file and if present must be the first child of the root

15.Quartz.Net

TimeZone problem https://forums.asp.net/t/2001087.aspx?Quartz+NET+scheduling+jobs+in+mvc+on+windows+azure http://mattrandle.me/azure-worker-role-and-quartz-net/ http://knightcodes.com/.net/2016/08/15/xml-configuration-for-quartz-net.html

16. RUN PYTHON IN .NET

Running Python script from C# and working with the results https://medium.com/@dpursanov/running-python-script-from-c-and-working-with-the-results-843e68d230e5

http://devcenter.wintellect.com/jrobbins/pdb-files-what-every-developer-must-know

WorkingDirectory

processStartInfo start = new ProcessStartInfo();
processStartInfo start = new ProcessStartInfo();
start.FileName = "C:\\Python27\\python.exe";
Console.Write(args.Length);
// arg[0] = Path to your python script (example : "C:\\add_them.py")
// arg[1] = first arguement taken from  C#'s main method's args variable (here i'm passing a number : 5)
// arg[2] = second arguement taken from  C#'s main method's args variable ( here i'm passing a number : 6)
// pass these to your Arguements property of your ProcessStartInfo instance
start.Arguments = string.Format("{0} {1} {2}",args[0],args[1],args[2]);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start)){ 
				using (StreamReader reader = process.StandardOutput) { 
							string result = reader.ReadToEnd(); // this prints 11 
							Console.Write(result);
				}
}

issues:mvc ajax get empty data:

By default, the asp.net mvc does not allow an HTTP GET request with a JSON payload. You need to explicitly allow the behavior by using JsonRequestBehavior.AllowGet as the second parameter to the Json method like following.

return Json(returnObj, JsonRequestBehavior.AllowGet);

issues:JSON decoding: Unexpected token: StartArray

the value starts from the exception position should be deserialized as an object, not a string

issues: An asynchronous module or handler completed while an asynchronous operation was still pending

https://stackoverflow.com/questions/28805796/asp-net-controller-an-asynchronous-module-or-handler-completed-while-an-asynchr/28806198

That’s because Task.Factory.StartNew does something dangerous in ASP.NET. It doesn’t register the tasks execution with ASP.NET. This can lead to edge cases where a pool recycle executes, ignoring your background task completely, causing an abnormal abort. That is why you have to use a mechanism which registers the task, such as HostingEnvironment.QueueBackgroundWorkItem.

Updated:

Comments