在多线程应用程序中使用异步调用的简单方法
使用异步调用的简单方法
引言
运行异步任务可能是一件棘手的事情,尤其是对于初学者。 在附带的代码中,您会发现一个简单的 AsyncWorker
类,它可以让您的生活更轻松,即使您不了解所有背景知识。 我非常希望看到您对提供的代码的贡献,特别是对 ReportProgress
函数的贡献。
背景
我为什么要编写这个辅助类? 仅仅是因为我不喜欢 .NET BackgroundWorker
类以及与 IsBusy
参数相关的所有问题。 有时,即使您成功结束了异步任务,IsBusy
也不会从 true
过渡到 false
。 backgroundWorker
强制您在 while
循环中使用 Application.DoEvents
。 这对我来说太疯狂了。 也许还有其他正确使用它的方法,但我没有找到。 我试图遵循与 BackgroundWorker
相同的设计,以便替换尽可能简单。
Using the Code
如果您查看 BackgroundWorker
文档,那么对于您来说这将是显而易见的。 要初始化 AsyncWorker
,只需定义
AsyncCallback m_asyncWorker;
并在您的代码中的某个位置(构造函数)初始化它。
//By setting the maximumCount, we can simulate the simple ThreadPool.
//The maximumCount parameter tells you how many concurrent threads may be
//started simultaneously. Others will wait or be rejected if abortIfBusyParameter
//is set to true.
this.m_asyncWorker = new AsyncWorker(1);
//assign a background task
this.m_asyncWorker.DoWork += new DoWorkEventHandler(m_asyncWorker_DoWork);
您的后台任务可以是您喜欢的任何内容
void m_asyncWorker_DoWork(object sender, DoWorkEventArgs e) {
Console.WriteLine("Hello world! I was started asynchronously.");
}
最后,要调用后台工作者,只需输入
//because abortIfBusyParameter is set to true, RunWorkerAsync will
//return false (abort the call) if the previous call is still running.
if (!this.m_asyncWorker.RunWorkerAsync(true)) {
Console.WriteLine("Worker in use....");
}
通过将 RunWorkerAsync
参数 abortIfBusy
设置为 true
,您可以跳过此事件,如果先前的异步调用仍在运行。 通过将其设置为 false
,它将在队列中等待,并在 IsBusy
从 true
切换到 false
后立即触发。 此机制对于性能敏感型应用程序非常有用。 如果您有很多“低优先级”事件启动您的 AsyncCalls
,并且如果先前的异步调用仍在运行(IsBusy
),您可以决定是否应该启动另一个异步调用。
例如:如果您在屏幕上拖动一个对象,您不必每次都重新绘制它。 仅当 IsBusy
为 false
时才绘制它。 如果您想要更平滑的效果,只需增加 maximumCount
(您的线程池)。
最后,如果您需要回调,请订阅 RunWorkerCompleted
事件。
//assign to a RunWorkerCompleted. It is your callback event.
this.m_asyncWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(m_asyncWorker_RunWorkerCompleted);
关注点
希望这个工具现在能让您的生活更轻松。 请不要询问 JustDoSomething
类中的锁定问题。 它曾经是其他测试的一部分。
历史
- 2009年10月6日 - 首次发布 (Igor Alfirevic)