如何创build一个asynchronous方法

我在我的C#应用​​程序中有简单的方法,它从FTP服务器中挑选文件并parsing它,并将数据存储在数据库中。 我希望它是asynchronous的,以便用户在App上执行其他操作,一旦parsing完成,他必须得到消息“parsing已完成”。

我知道它可以通过asynchronous方法调用来实现,但我不知道该怎么做,谁能帮助我?

您需要使用委托和它们包含的BeginInvoke方法以asynchronous方式运行另一个方法。 由委托运行的方法的结束,您可以通知用户。 例如:

 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); } } 

请阅读http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

试试这个方法

 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(); }); } 

用法:

 RunAsynchronously( () => { picks file from FTP server and parses it}, () => { Console.WriteLine("Parsing is done"); } ); 

任何时候你正在做一些asynchronous的事情,你都使用一个单独的线程,一个新的线程或一个从线程池中取得的线程。 这意味着任何asynchronous操作都必须非常小心与其他线程的交互。

一种方法是将asynchronous线程(称为线程“A”) 的代码及其所有数据放入另一个类(称为类“A”)。 确保线程“A”只访问类“A”中的数据。 如果线程“A”只触及类“A”,并且没有其他线程触及类“A”的数据,那么还有一个问题:

 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); } } 

请注意,从外部触及的AsyncClass的唯一部分是它的公共接口,而数据的唯一部分是CompletionTime 。 请注意, 只有在asynchronous任务完成后才会触及。 这意味着任何事情都不能干涉内部工作的任务,也不能干涉其他任何事情。

这里有两个关于C#线程的链接

  • 在C#中的线程
  • .NET中的multithreading:简介和build议

我会开始阅读有关BackgroundWorker类

在Asp.Net中,我使用了很多静态方法来完成作业。 如果仅仅是一个我不需要任何回应或地位的工作,我会做一些简单的事情。 正如你所看到的,我可以select调用ResizeImages或ResizeImagesAsync,这取决于我是否要等待它完成

代码解释:我使用http://imageresizing.net/来调整图像尺寸/裁剪图像,SaveBlobPng方法是将图像存储到Azure(云),但是由于这个代码并不包含这个代码。; 尽pipe这是一个很耗时的任务

 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(); } } 

或者去线程,所以你不必与代表打扰

 private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions) { Thread t = new Thread (() => ResizeImages(tempuri, versions, null, null)); t.Start(); } 

ThreadPool.QueueUserWorkItem是让一个进程在另一个线程上运行的最快方法。

请注意,UI对象具有“线程关联性”,不能从除创build它们之外的任何线程访问。

因此,除了检出ThreadPool(或通过委托使用asynchronous编程模型)之外,还需要检查Dispatchers (wpf)或InvokeRequired (winforms)。

最后,你将不得不使用某种线程。 它基本上工作的方式是用一个新的线程启动一个函数,直到函数结束。

如果你正在使用Windows窗体,那么他们有一个很好的包装就是调用Background Worker。 它允许你在后台工作,不用lockingUI表单,甚至提供一种与表单进行沟通的方式,并提供进度更新事件。

背景工作者