我编写了一个检查POP3帐户的类,我希望它在UI线程以外的线程上执行。
为此,我选择了异步路由。
为了从pop3delegate.BeginInvoke(null,null)获取结果,我需要调用EndInvoke,但是在UI线程中执行此操作会阻止UI无法使用。
我可以使用IAsyncResult对象并检查IsComplete属性,但这涉及放入一个检查循环,这反过来会锁定UI。
我正在寻找的是从POP3类中获取完成百分比或某种状态的方法,后者又会更新UI并允许UI用于执行其他任务。我还需要在某个时刻调用EndInvoke方法,以便捕获工作线程上抛出的任何异常。
有什么建议吗?
答案 0 :(得分:3)
尝试使用BackgroundWorker类,它的设计完全符合您的需要。
有关msdn的示例和更多详细信息:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
答案 1 :(得分:0)
尝试Backgroundworker课程。
答案 2 :(得分:0)
使用BackgroundWorker。它还为您节省了在UI和后台传输之间来回编组数据的麻烦,并且它允许进度通知和取消。
答案 3 :(得分:0)
使用event和threadpool
var asyncResult = pop3delegate.BeginInvoke(null,null);
ThreadPool.RegisterWaitForSingleObject(
asyncResult.WaitHandle, FunctionToCallWhenDone, null, TimeSpan.Infinite, true);
当数据到达时,这将调用FunctionToCallWhenDone。你也使用ThreadPool,它应该比创建自己的线程便宜。但是,正如Kurt Schelfthout指出你必须做一些像uielement.Invoke(()=> {some code})这样的东西来改变UI。
答案 4 :(得分:0)
您不需要阻塞或循环,只需将回调方法(委托)作为BeginInvoke调用的第一个参数传递,此处您可以调用EndInvoke进程异常等。
private delegate int LongRunningTaskHandler();
static void Main(string[] args) {
LongRunningTaskHandler handler = LongRunningTask;
handler.BeginInvoke(MyCallBack, null);
Console.ReadLine();
}
private static void MyCallBack(IAsyncResult ar) {
var result = (LongRunningTaskHandler)((AsyncResult) ar).AsyncDelegate;
Console.WriteLine(result.EndInvoke(ar));
}
public static int LongRunningTask()
{
Thread.Sleep(5000);
return 42;
}