C# 在UI线程上异步调用同步方法

C# 在UI线程上异步调用同步方法,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,我已经编写了一个检查POP3帐户的类,我希望它在UI线程以外的线程上执行 为此,我选择了异步路由 为了从pop3delegate.BeginInvoke(null,null)获取结果,我需要调用EndInvoke,但在UI线程块中执行此操作会导致UI不可用 我可以使用IAsyncResult对象并检查IsComplete属性,但这需要放入一个循环进行检查,这反过来会锁定UI 我要寻找的是一种从POP3类获得完成百分比或某种状态的方法,它反过来更新UI,还允许UI用于执行其他任务。我还需要在某个时

我已经编写了一个检查POP3帐户的类,我希望它在UI线程以外的线程上执行

为此,我选择了异步路由

为了从pop3delegate.BeginInvoke(null,null)获取结果,我需要调用EndInvoke,但在UI线程块中执行此操作会导致UI不可用

我可以使用IAsyncResult对象并检查IsComplete属性,但这需要放入一个循环进行检查,这反过来会锁定UI

我要寻找的是一种从POP3类获得完成百分比或某种状态的方法,它反过来更新UI,还允许UI用于执行其他任务。我还需要在某个时刻调用EndInvoke方法,以便捕获工作线程上抛出的任何异常


有什么建议吗?

尝试使用BackgroundWorker类,它的设计正是为了满足您的需要


有关msdn的示例和更多详细信息:

尝试该类。

使用BackgroundWorker。它还为您省去了在UI和后台trheads之间来回编组数据的麻烦,并允许进度通知和取消。

使用事件和线程池

var asyncResult = pop3delegate.BeginInvoke(null,null);
ThreadPool.RegisterWaitForSingleObject(
    asyncResult.WaitHandle, FunctionToCallWhenDone, null, TimeSpan.Infinite, true);

这将在数据到达时调用函数调用whendone。您还使用了ThreadPool,这应该比创建自己的线程更便宜。但是,正如Kurt Schelfthout所指出的,您必须执行类似uielement.Invoke(()=>{some code})的操作才能更改UI。

您不需要阻塞或循环,只需将回调方法(委托)作为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;
}

我读过一篇文章,它似乎是一种基于事件的报告方式,但是,仔细想想,我可以在我的pop3类中设置事件,并将UI方法挂接到它们上以显示结果。回调方法不会给我一个进度指示器,只是任务完成了。我需要定期检查。