How to create an asynchronous method
Solution 1
You need to use delegates and the BeginInvoke
method that they contain to run another method asynchronously. A the end of the method being run by the delegate, you can notify the user. For example:
class MyClass
{
private delegate void SomeFunctionDelegate(int param1, bool param2);
private SomeFunctionDelegate sfd;
public MyClass()
{
sfd = new SomeFunctionDelegate(this.SomeFunction);
}
private void SomeFunction(int param1, bool param2)
{
// Do stuff
// Notify user
}
public void GetData()
{
// Do stuff
sfd.BeginInvoke(34, true, null, null);
}
}
Read up at http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx
Solution 2
try this method
public static void RunAsynchronously(Action method, Action callback) {
ThreadPool.QueueUserWorkItem(_ =>
{
try {
method();
}
catch (ThreadAbortException) { /* dont report on this */ }
catch (Exception ex) {
}
// note: this will not be called if the thread is aborted
if (callback!= null) callback();
});
}
Usage:
RunAsynchronously( () => { picks file from FTP server and parses it},
() => { Console.WriteLine("Parsing is done"); } );
Solution 3
Any time you're doing something asynchronous, you're using a separate thread, either a new thread, or one taken from the thread pool. This means that anything you do asynchronously has to be very careful about interactions with other threads.
One way to do that is to place the code for the async thread (call it thread "A") along with all of its data into another class (call it class "A"). Make sure that thread "A" only accesses data in class "A". If thread "A" only touches class "A", and no other thread touches class "A"'s data, then there's one less problem:
public class MainClass
{
private sealed class AsyncClass
{
private int _counter;
private readonly int _maxCount;
public AsyncClass(int maxCount) { _maxCount = maxCount; }
public void Run()
{
while (_counter++ < _maxCount) { Thread.Sleep(1); }
CompletionTime = DateTime.Now;
}
public DateTime CompletionTime { get; private set; }
}
private AsyncClass _asyncInstance;
public void StartAsync()
{
var asyncDoneTime = DateTime.MinValue;
_asyncInstance = new AsyncClass(10);
Action asyncAction = _asyncInstance.Run;
asyncAction.BeginInvoke(
ar =>
{
asyncAction.EndInvoke(ar);
asyncDoneTime = _asyncInstance.CompletionTime;
}, null);
Console.WriteLine("Async task ended at {0}", asyncDoneTime);
}
}
Notice that the only part of AsyncClass
that's touched from the outside is its public interface, and the only part of that which is data is CompletionTime
. Note that this is only touched after the asynchronous task is complete. This means that nothing else can interfere with the tasks inner workings, and it can't interfere with anything else.
Solution 4
Here are two links about threading in C#
I'd start to read about the BackgroundWorker class
Solution 5
In Asp.Net I use a lot of static methods for jobs to be done. If its simply a job where I need no response or status, I do something simple like below. As you can see I can choose to call either ResizeImages or ResizeImagesAsync depending if I want to wait for it to finish or not
Code explanation: I use http://imageresizing.net/ to resize/crop images and the method SaveBlobPng is to store the images to Azure (cloud) but since that is irrelevant for this demo I didn't include that code. Its a good example of time consuming tasks though
private delegate void ResizeImagesDelegate(string tempuri, Dictionary<string, string> versions);
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
ResizeImagesDelegate worker = new ResizeImagesDelegate(ResizeImages);
worker.BeginInvoke(tempuri, versions, deletetemp, null, null);
}
private static void ResizeImages(string tempuri, Dictionary<string, string> versions)
{
//the job, whatever it might be
foreach (var item in versions)
{
var image = ImageBuilder.Current.Build(tempuri, new ResizeSettings(item.Value));
SaveBlobPng(image, item.Key);
image.Dispose();
}
}
Or going for threading so you dont have to bother with Delegates
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
Thread t = new Thread (() => ResizeImages(tempuri, versions, null, null));
t.Start();
}
Prashant Cholachagudda
Updated on January 07, 2020Comments
-
Prashant Cholachagudda over 4 years
I have simple method in my C# app, it picks file from FTP server and parses it and stores the data in DB. I want it to be asynchronous, so that user perform other operations on App, once parsing is done he has to get message stating "Parsing is done".
I know it can achieved through asynchronous method call but I dont know how to do that can anybody help me please??
-
Prashant Cholachagudda almost 15 yearsThanks for response ,is it possible to do it without threads, may be with delegates?
-
tanascius almost 15 yearsYou can use a BeginInvoke(), but that invokes another thread, too. Really, have a look at the BackgroundWorker - it is easy to use and provides a notify when the job is done.
-
Callum Rogers over 13 yearsNote that rather than declaring and using a
SomeFunctionDelegate
you can just use aAction<int,bool>
and similarly aFunc<Type1,Type2,ReturnType>
for methods that are not void. -
net_prog over 12 yearsnew Action<int, string>(MethodName).BeginInvoke(1, "text", null, null);
-
Jacob about 12 yearsThat "Async task ended at {0}" string isn't printed after the async task finishes...
-
Gennady Vanin Геннадий Ванин over 11 yearsPlz correct your statement "Any time you're doing something asynchronous, you're using a separate thread". It is wrong. Check Asynchrony in C# 5.0 part Four: It's not magic
-
John Saunders over 11 yearsIt's always a separate thread, logically, even if, physically, the same thread can be reused.
-
Royi Namir about 11 yearsthis is Asynchronous delegates and not asynchronous methods.Asynchronous methods follow a similar protocol outwardly, but they exist to solve a much more difficult problem
-
Callum Rogers about 11 years@Royi: I think you are confused, this answer is nearly 4 years old and was before the time of
async
and such so is appropriate for the question. -
Royi Namir about 11 years@CallumRogers No I'm not. You are. read this i.stack.imgur.com/i3pH2.jpg and then this i.stack.imgur.com/BcX33.jpg they all taken from c# book from joe albahari v4. ( Fw4 , and has nothing to do with asunc) they are all from here albahari.com/threading/#_Asynchronous_delegates). you should Edit your answer. it is not a an asynchrouns method but delegate.
-
Callum Rogers about 11 years@Royi: I see what you mean - however just because the question is asking about asynchronous methods does not mean he's referring to the same thing that you are. OP is more requesting a way to call a method asynchronously and this is the correct answer. I have to say I've never really seen it called
asynchronous methods
- I think you meanasynchronous operation
instead. -
Royi Namir about 11 yearsYou mean "I thought you meant...". they are actually different things.The OP probably don't know that there are 2 subjects. he asked about asynchronous methods and you gave him an answer about Asynchronous delegates.