Http Async Post in c#,Raspberry Pi ,data not post - c#

The HTTP async method not working and the data never post when I run this in raspberry pi. The distance monitoring method still running but just the data doesn't post Codes
IUltrasonicRangerSensor sensor = DeviceFactory.Build.UltraSonicSensor(Pin.DigitalPin8);
private int distance = 200;
int count = 0;
ILed ledRed = DeviceFactory.Build.Led(Pin.DigitalPin5);
ILed ledGreen = DeviceFactory.Build.Led(Pin.DigitalPin6);
private void Sleep(int NoOfMs)
{
Task.Delay(NoOfMs).Wait();
}
private async void startDistanceMonitoring()
{
await Task.Delay(100);
int distanceRead = 200;
while (true)
{
Sleep(1000);
count++;
distanceRead = sensor.MeasureInCentimeters();
if (distanceRead < 200 && distanceRead > 0)
distance = distanceRead;
await sendtoapi();
}
}
private async Task sendtoapi()
{
using (var client = new HttpClient())
{
var values = new Dictionary<string, string>
{
{ "userName", "qwee" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://google.com", content);
Sleep(10000);
var responseString = await response.Content.ReadAsStringAsync();
}
}
public void Run(IBackgroundTaskInstance taskInstance)
{
startDistanceMonitoring();
Sleep(300);
Debug.WriteLine("count = " + count + " ,distance=" + distance);
while (true)
{
if (distance >= 150)
{
Debug.WriteLine("EMPTY LOT");
Sleep(1000);
ledGreen.ChangeState(SensorStatus.On);
ledRed.ChangeState(SensorStatus.Off);
}
}
}

When you do async/await you basically want to make all(most) of your methods work in an async/await manner. At the moment your mixing async and non async method calls. This is called blocking in an async context and it should be avoided, not least of which because it can lead to deadlocks. I'd suggest you have a read though Async/Await - Best Practices in Asynchronous Programming
In general (and to simplify the problem somewhat) all your methods should have the signature
public async Task method()
{
}
and all your methods should be called:
await method();
Here are a couple of things your doing wrong
private async void startDistanceMonitoring()
Never use async void (these are for async event handlers only)
private void Sleep(int NoOfMs)
{
Task.Delay(NoOfMs).Wait();
}
this is blocking, this should be
private async Task Sleep(int NoOfMs)
{
await Task.Delay(NoOfMs);
}
When you call:
startDistanceMonitoring();
startDistanceMonitoring is an async method, yet your not awaiting it. So your program may very well terminate before it's completed. This should be:
await startDistanceMonitoring();
You do this incorrectly all over this block of code. Always call async methods with an await.
Your entry method isn't async, public void Run(IBackgroundTaskInstance taskInstance) should be public async Task Run(IBackgroundTaskInstance taskInstance)

Related

How to use await, async and Task in asynchronous programming

This is the first time I'm writing any asynchronous code. I am getting a compile error that says:
Cannot implicitly convert type void to int
while the function is returning an int.
public class Function
{
IAmazonS3 s3client = new AmazonS3Client(RegionEndpoint.USEast1);
public async Task<int> ListS3ObjectsAsync(string bucketName, IAmazonS3 client)
{
ListObjectsRequest request = new ListObjectsRequest();
request.BucketName = bucketName;
ListObjectsResponse response = await client.ListObjectsAsync(request);
do
{
if (response.IsTruncated)
request.Marker = response.NextMarker;
else
request = null;
} while (request != null);
var len = response.S3Objects.Count;
return len;
}
public void FunctionHandler(S3Event evnt, ILambdaContext context)
{
// Here I'm getting the compile error
int x = ListS3ObjectsAsync(evnt.Records?[0].S3.Bucket.Name, s3client).Wait();
}
}
Visual Studio screenshot:
Because ListS3ObjectsAsync method returns a Task<int>, which is an asynchronous representation of getting an int, so in order to get the result, you either need to await the task like this:
int x = await ListS3ObjectsAsync
But that will require you to make the FunctionHandler async aswell.
Or you can call .Result on the task like this
var task = ListS3ObjectsAsync
int x = task.Result
Note that this is a blocking operation and mixing async and non async code is bad practise.
.Wait method only waits for the task to complete, but does not return the Result
You shouldn't block on async code, so the best solution is to use await instead of Wait:
public void FunctionHandler(S3Event evnt, ILambdaContext context)
{
int x = await ListS3ObjectsAsync(evnt.Records?[0].S3.Bucket.Name, s3client);
}
The compiler will then tell you the next part of the solution: FunctionHandler must be made async and its return type changed to Task, i.e.:
public async Task FunctionHandlerAsync(S3Event evnt, ILambdaContext context)
{
int x = await ListS3ObjectsAsync(evnt.Records?[0].S3.Bucket.Name, s3client);
}
The "growth" of async like this is normal.

Issue with CancellationTokenSource in C#

I am trying to create a helper class for sending some information periodically to backend server.
Attaching the code below.
public class HeartBeatService
{
private CancellationToken _cancellationToken;
private CancellationTokenSource _cancellationTokenSource;
public void StartHeartBeatService(TimeSpan timeSpan)
{
_cancellationTokenSource = new CancellationTokenSource();
_cancellationToken = _cancellationTokenSource.Token;
Task.Run(async () =>
{
while (!_cancellationToken.IsCancellationRequested)
{
SendHeartBeatToAzure();
try
{
await Task.Delay(timeSpan, _cancellationToken);
}
catch
{
break;
}
}
});
}
public void SuspendHeartBeatService()
{
_cancellationTokenSource?.Cancel();
}
private async void SendHeartBeatToAzure()
{
var platformService = ServiceLocator.Get<IPlatformService>();
var location = await platformService?.GetPositionAsync();
if (!double.IsNaN(location.Item1) && !double.IsNaN(location.Item2))
{
Debug.WriteLine($"Triggering Heartbeat with location{location.Item1},{location.Item2}");
//TODO Invoke heartbeat api call.
}
}
}
The code for sending the information to server is working fine.
But there is some issue with CancellationToken which is not working/it is not cancelling.
not sure what's wrong with the implementation.
Change the signature of the SendHeartBeatToAzure to return a Task, so that it can be awaited:
private async Task SendHeartBeatToAzure()
Then await the task returned by the method inside the loop. To achieve a stable and consisted heartbeat, it is a good idea to create the Task.Delay task before calling the method:
Task.Run(async () =>
{
while (true)
{
var delayTask = Task.Delay(timeSpan, _cancellationToken);
await SendHeartBeatToAzure();
await delayTask;
}
});
As a side note, you should probably store the task returned by Task.Run as a readonly property of the HeartBeatService class, so that the status of the task can be monitored.

Task.WaitAll() hangs in console application

I have a console application in which I need to retrieve some data from 4 different sites. I placed each HTTP request in a task and I wait for them all to complete.
It was working when I only had to get data from 2 sites. but then I needed to add other sources of data and when adding 3 or more requests, the Task.WaitAll() hangs.
Below is my code.
The reason I ended up using Task.WaitAll() was because I need to stop and prevent the console application from exiting - i.e. I need to perform other tasks only after all the HTTP requests come back with data.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static Task[] tasks = new Task[3];
static void Main(string[] args)
{
try
{
Run();
}
catch (System.Exception ex)
{
}
}
public static async void Run()
{
//works when using one or two tasks
tasks[0] = HttpExtensions.GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
tasks[1] = HttpExtensions.GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
//fails when add 3 or more task
tasks[2] = HttpExtensions.GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
//tasks[3] = HttpExtensions.GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
Task.WaitAll(tasks);
var result4 = ((Task<Stream>)tasks[2]).Result;
}
}
public static class HttpExtensions
{
public static Stopwatch sw;
public static long http_ticks = 0;
public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request)
{
var taskComplete = new TaskCompletionSource<HttpWebResponse>();
request.BeginGetResponse(asyncResponse =>
{
try
{
HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
taskComplete.TrySetResult(someResponse);
}
catch (WebException webExc)
{
HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
taskComplete.TrySetResult(failedResponse);
}
}, request);
return taskComplete.Task;
}
public static async Task<Stream> GetMyData(string urlToCall)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToCall);
request.Method = HttpMethod.Get;
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
//using (var sr = new StreamReader(response.GetResponseStream()))
//{
return response.GetResponseStream();
//}
}
}
public static class HttpMethod
{
public static string Head { get { return "HEAD"; } }
public static string Post { get { return "POST"; } }
public static string Put { get { return "PUT"; } }
public static string Get { get { return "GET"; } }
public static string Delete { get { return "DELETE"; } }
public static string Trace { get { return "TRACE"; } }
public static string Options { get { return "OPTIONS"; } }
public static string Connect { get { return "CONNECT"; } }
public static string Patch { get { return "PATCH"; } }
}
}
There a number of concerns.
First, as I mentioned in the comments above, by not returning a Task you are more or less hanging your application since it can't tell when the Task is completed.
However, once you change the Run() method to return a task, you need to invoke it via a Task.Run call in your Main method.
Second, you are over-complicating your code by using WebClient. Switch to HttpClient and take advantage of its natural async/await API.
Third, you aren't actually awaiting anything in your Run() method so changing it to a task does nothing since you aren't awaiting a result which will cause it to run synchronously (no pun intended). Update your method to await a result.
Finally, WaitAll blocks the thread, which may not be what you want. You can use WhenAll instead and await that call, allowing your application to release the thread while your tasks run.
Below is a complete, working example of my recommended modifications, simplified to show a working program. The Main method recommendation is taken from https://social.msdn.microsoft.com/Forums/vstudio/en-US/fe9acdfc-66cd-4b43-9460-a8053ca51885/using-new-asyncawait-in-console-app?forum=netfxbcl
class Program
{
static Task[] tasks = new Task[3];
static HttpClient _client = new HttpClient();
static void Main(string[] args)
{
Console.WriteLine("Main start");
Task t = Run();
t.ContinueWith((str) =>
{
Console.WriteLine(str.Status.ToString());
Console.WriteLine("Main end");
});
t.Wait();
}
public static async Task Run()
{
tasks[0] = GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
tasks[1] = GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
tasks[2] = GetMyData("http://www.w3.org/TR/PNG/iso_8859-1.txt");
await Task.WhenAll(tasks);
var result4 = (await (Task<Stream>)tasks[2]);
}
public static async Task<Stream> GetMyData(string urlToCall)
{
return await _client.GetStreamAsync(urlToCall);
}
}
I think the issue is more of understanding Task and async await; and I may be wrong so apologies up front.
Task is a managed thread that goes into a thread pool. Task has a Task.Result of Type T.
You can create a Task and then Start it and then Wait it. (Never a good idea to start and then immediately wait a task but for understanding...)
var task = new Task(() => DoWork());
task.Start();
task.Wait();
The task will perform the DoWork() method in a new thread.
The calling thread will BLOCK at task.Wait();
You can also give a Task a ContinueWith Action that will perform the remaining work on the calling thread.
var task = new Task(() => DoWorkOnNewThread());
task.ContinueWith(() => MainThreadWork());
task.Start(); //Notice no more task.Wait();
So, if you're following that little bit then you can sort of use async await correctly.
The async keyword tells the compiler to wrap all remaing code AFTER reaching the await keyword WHERE A GetAwaiter() is returned. This is important because until you actually create a task (preferably started also) and return it then you have no GetAwaiter();
private Task DoWorkAsync()
{
var task = new Task(() => DoWork());
task.Start();
return task;
}
private async void Method()
{
//Main thread code...
await DoWorkAsync(); //Returns to whoever called Method()
//More main thread code to be QUEUED to run AFTER DoWorkAsync is complete.
//This portion of code, when compiled, is essentially wrapped in the ContinueWith(...
}
So if you're still following along then here's the kicker. You're on the same thread UNTIL you return a GetAwaiter() which is only found in a Task. If the Task has never started then you'll await that Task forever technically. So here's some comments showing the thread transitions.
private Task DoWorkAsync()
{
Debug.WriteLine("Still on main thread")
var task = new Task(() =>
{
Debug.WriteLine("On background thread");
});
task.Start(); //On main thread.
return task; //On main thread.
}
private async void Method()
{
Debug.WriteLine("On main thread");
await DoWorkAsync(); //returns to caller after DoWorkAsync returns Task
Debug.WriteLine("Back on main thread"); //Works here after the task DoWorkAsync returned is complete
}
An easier way to return the task running is to return Task.Run(() => DoWork()); If you look at the return value of Run it is Task and that task has already been started.
Forgive me if this isn't what you wanted but I felt like there is more of a confusion about using async await correctly than there is confusion about your code. I may be wrong but I felt that if you could understand more about the Task itself and how async await works you would see your issue. If this isn't what you're looking for I'll delete the answer.

Queue of async tasks with throttling which supports muti-threading

I need to implement a library to request vk.com API. The problem is that API supports only 3 requests per second. I would like to have API asynchronous.
Important: API should support safe accessing from multiple threads.
My idea is implement some class called throttler which allow no more than 3 request/second and delay other request.
The interface is next:
public interface IThrottler : IDisposable
{
Task<TResult> Throttle<TResult>(Func<Task<TResult>> task);
}
The usage is like
var audio = await throttler.Throttle(() => api.MyAudio());
var messages = await throttler.Throttle(() => api.ReadMessages());
var audioLyrics = await throttler.Throttle(() => api.AudioLyrics(audioId));
/// Here should be delay because 3 requests executed
var photo = await throttler.Throttle(() => api.MyPhoto());
How to implement throttler?
Currently I implemented it as queue which is processed by background thread.
public Task<TResult> Throttle<TResult>(Func<Task<TResult>> task)
{
/// TaskRequest has method Run() to run task
/// TaskRequest uses TaskCompletionSource to provide new task
/// which is resolved when queue processed til this element.
var request = new TaskRequest<TResult>(task);
requestQueue.Enqueue(request);
return request.ResultTask;
}
This is shorten code of background thread loop which process the queue:
private void ProcessQueue(object state)
{
while (true)
{
IRequest request;
while (requestQueue.TryDequeue(out request))
{
/// Delay method calculates actual delay value and calls Thread.Sleep()
Delay();
request.Run();
}
}
}
Is it possible to implement this without background thread?
So we'll start out with a solution to a simpler problem, that of creating a queue that process up to N tasks concurrently, rather than throttling to N tasks started per second, and build on that:
public class TaskQueue
{
private SemaphoreSlim semaphore;
public TaskQueue()
{
semaphore = new SemaphoreSlim(1);
}
public TaskQueue(int concurrentRequests)
{
semaphore = new SemaphoreSlim(concurrentRequests);
}
public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
{
await semaphore.WaitAsync();
try
{
return await taskGenerator();
}
finally
{
semaphore.Release();
}
}
public async Task Enqueue(Func<Task> taskGenerator)
{
await semaphore.WaitAsync();
try
{
await taskGenerator();
}
finally
{
semaphore.Release();
}
}
}
We'll also use the following helper methods to match the result of a TaskCompletionSource to a `Task:
public static void Match<T>(this TaskCompletionSource<T> tcs, Task<T> task)
{
task.ContinueWith(t =>
{
switch (t.Status)
{
case TaskStatus.Canceled:
tcs.SetCanceled();
break;
case TaskStatus.Faulted:
tcs.SetException(t.Exception.InnerExceptions);
break;
case TaskStatus.RanToCompletion:
tcs.SetResult(t.Result);
break;
}
});
}
public static void Match<T>(this TaskCompletionSource<T> tcs, Task task)
{
Match(tcs, task.ContinueWith(t => default(T)));
}
Now for our actual solution what we can do is each time we need to perform a throttled operation we create a TaskCompletionSource, and then go into our TaskQueue and add an item that starts the task, matches the TCS to its result, doesn't await it, and then delays the task queue for 1 second. The task queue will then not allow a task to start until there are no longer N tasks started in the past second, while the result of the operation itself is the same as the create Task:
public class Throttler
{
private TaskQueue queue;
public Throttler(int requestsPerSecond)
{
queue = new TaskQueue(requestsPerSecond);
}
public Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
{
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
var unused = queue.Enqueue(() =>
{
tcs.Match(taskGenerator());
return Task.Delay(TimeSpan.FromSeconds(1));
});
return tcs.Task;
}
public Task Enqueue<T>(Func<Task> taskGenerator)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
var unused = queue.Enqueue(() =>
{
tcs.Match(taskGenerator());
return Task.Delay(TimeSpan.FromSeconds(1));
});
return tcs.Task;
}
}
I solved a similar problem using a wrapper around SemaphoreSlim. In my scenario, I had some other throttling mechanisms as well, and I needed to make sure that requests didn't hit the external API too often even if request number 1 took longer to reach the API than request number 3. My solution was to use a wrapper around SemaphoreSlim that had to be released by the caller, but the actual SemaphoreSlim would not be released until a set time had passed.
public class TimeGatedSemaphore
{
private readonly SemaphoreSlim semaphore;
public TimeGatedSemaphore(int maxRequest, TimeSpan minimumHoldTime)
{
semaphore = new SemaphoreSlim(maxRequest);
MinimumHoldTime = minimumHoldTime;
}
public TimeSpan MinimumHoldTime { get; }
public async Task<IDisposable> WaitAsync()
{
await semaphore.WaitAsync();
return new InternalReleaser(semaphore, Task.Delay(MinimumHoldTime));
}
private class InternalReleaser : IDisposable
{
private readonly SemaphoreSlim semaphoreToRelease;
private readonly Task notBeforeTask;
public InternalReleaser(SemaphoreSlim semaphoreSlim, Task dependantTask)
{
semaphoreToRelease = semaphoreSlim;
notBeforeTask = dependantTask;
}
public void Dispose()
{
notBeforeTask.ContinueWith(_ => semaphoreToRelease.Release());
}
}
}
Example usage:
private TimeGatedSemaphore requestThrottler = new TimeGatedSemaphore(3, TimeSpan.FromSeconds(1));
public async Task<T> MyRequestSenderHelper(string endpoint)
{
using (await requestThrottler.WaitAsync())
return await SendRequestToAPI(endpoint);
}
Here is one solution that uses a Stopwatch:
public class Throttler : IThrottler
{
private readonly Stopwatch m_Stopwatch;
private int m_NumberOfRequestsInLastSecond;
private readonly int m_MaxNumberOfRequestsPerSecond;
public Throttler(int max_number_of_requests_per_second)
{
m_MaxNumberOfRequestsPerSecond = max_number_of_requests_per_second;
m_Stopwatch = Stopwatch.StartNew();
}
public async Task<TResult> Throttle<TResult>(Func<Task<TResult>> task)
{
var elapsed = m_Stopwatch.Elapsed;
if (elapsed > TimeSpan.FromSeconds(1))
{
m_NumberOfRequestsInLastSecond = 1;
m_Stopwatch.Restart();
return await task();
}
if (m_NumberOfRequestsInLastSecond >= m_MaxNumberOfRequestsPerSecond)
{
TimeSpan time_to_wait = TimeSpan.FromSeconds(1) - elapsed;
await Task.Delay(time_to_wait);
m_NumberOfRequestsInLastSecond = 1;
m_Stopwatch.Restart();
return await task();
}
m_NumberOfRequestsInLastSecond++;
return await task();
}
}
Here is how this code can be tested:
class Program
{
static void Main(string[] args)
{
DoIt();
Console.ReadLine();
}
static async Task DoIt()
{
Func<Task<int>> func = async () =>
{
await Task.Delay(100);
return 1;
};
Throttler throttler = new Throttler(3);
for (int i = 0; i < 10; i++)
{
var result = await throttler.Throttle(func);
Console.WriteLine(DateTime.Now);
}
}
}
You can use this as Generic
public TaskThrottle(int maxTasksToRunInParallel)
{
_semaphore = new SemaphoreSlim(maxTasksToRunInParallel);
}
public void TaskThrottler<T>(IEnumerable<Task<T>> tasks, int timeoutInMilliseconds, CancellationToken cancellationToken = default(CancellationToken)) where T : class
{
// Get Tasks as List
var taskList = tasks as IList<Task<T>> ?? tasks.ToList();
var postTasks = new List<Task<int>>();
// When the first task completed, it will flag
taskList.ForEach(x =>
{
postTasks.Add(x.ContinueWith(y => _semaphore.Release(), cancellationToken));
});
taskList.ForEach(x =>
{
// Wait for open slot
_semaphore.Wait(timeoutInMilliseconds, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
x.Start();
});
Task.WaitAll(taskList.ToArray(), cancellationToken);
}
Edit: this solution works but use it only if it is ok to process all request in serial (in one thread). Otherwise use solution accepted as answer.
Well, thanks to Best way in .NET to manage queue of tasks on a separate (single) thread
My question is almost duplicate except adding delay before execution, which is actually simple.
The main helper here is SemaphoreSlim class which allows to restrict degree of parallelism.
So, first create a semaphore:
// Semaphore allows run 1 thread concurrently.
private readonly SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
And, final version of throttle looks like
public async Task<TResult> Throttle<TResult>(Func<Task<TResult>> task)
{
await semaphore.WaitAsync();
try
{
await delaySource.Delay();
return await task();
}
finally
{
semaphore.Release();
}
}
Delay source is also pretty simple:
private class TaskDelaySource
{
private readonly int maxTasks;
private readonly TimeSpan inInterval;
private readonly Queue<long> ticks = new Queue<long>();
public TaskDelaySource(int maxTasks, TimeSpan inInterval)
{
this.maxTasks = maxTasks;
this.inInterval = inInterval;
}
public async Task Delay()
{
// We will measure time of last maxTasks tasks.
while (ticks.Count > maxTasks)
ticks.Dequeue();
if (ticks.Any())
{
var now = DateTime.UtcNow.Ticks;
var lastTick = ticks.First();
// Calculate interval between last maxTasks task and current time
var intervalSinceLastTask = TimeSpan.FromTicks(now - lastTick);
if (intervalSinceLastTask < inInterval)
await Task.Delay((int)(inInterval - intervalSinceLastTask).TotalMilliseconds);
}
ticks.Enqueue(DateTime.UtcNow.Ticks);
}
}

Entity object inside Async and Await process

I'm trying to use Async and Await for upload process. I created a small code to see if it works.
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
TestAsync().Wait();
}
}
public static async Task TestAsync()
{
await Task.Run(() => {
Thread.Sleep(1000);
var context = new CommonEntities();
context.AddToDummies(new Dummy { TimeStamp = DateTime.Now, Caption = "Async" });
context.SaveChanges();
});
}
}
But for some reason, it never gets to Console.WriteLine. If I replaced var context = new EntityObject(); with var stringBuilder = new StringBuilder(); then it worked.
The idea is that I will create a method which has many complex procedures of saving and updating database as well as calling a webservice and store the result to database etc. Let say that method is called MethodA.
public static async void test()
{
await Task.Run(() => MethodA());
}
But before going further, I am stuck in this simple test. Any idea why that is?
You shouldn't be using async void anywhere other than an event handler.
async void doesn't allow the caller to wait (asynchronously or otherwise) for the operation to complete, it just moves on. In your case it reaches the end of Main and the application ends before you get a chance to reach the Console.WriteLine.
You need to change TestAsync to return a Task and wait for it in Main:
static void Main()
{
TestAsync().Wait();
}
public static async Task TestAsync()
{
await Task.Run(() =>
{
var objectContext = new CommonEntities();
Console.WriteLine("Processed");
});
}

Categories

Resources