在不阻塞 gui 线程的情况下工作

Do work without blocking the gui thread

我有一个 c# windows 表单应用程序并使用了一个不提供异步等待功能的库。

当我按下一个按钮时,我想做一些工作(网络请求)。 在做这项工作时,我不想冻结我的图形用户界面。

我尝试了几种方法,例如:

public static Task<bool> LoginUser(string username, string password)
{
    return Task.Factory.StartNew(() =>
    {
        try
        {
            session = new AuthenticatedSession<User>(new User(username), Cryptography.GetMd5(password));

            return true;
        }
        catch (InvalidAuthenticationException)
        {
            return false;
        }
    });
}

当我调用 LoginUser("foo", "bar").Result 时,GUI 会冻结,直到工作完成(我知道这不是异步的,因为我不能等待 new AuthenticatedSession<..

所以我寻找类似的东西:

  1. 创建一个以动作作为参数的线程
  2. Return 来自线程的值
  3. 结束话题

尝试强制使用新线程(或 WorkerThread)而不是使用 TaskFactory。

Thread t = new Thread (delegate()
{
    try
    {
        session = new AuthenticatedSession<User>(new User(username), Cryptography.GetMd5(password));
        Success();  //coded below
    }
    catch (InvalidAuthenticationException)
    {
        Fail();
    }     
});
t.Start();

你的列表要求我们 return 一个值,我们真正能做的就是调用一个方法或设置状态来指示 return 值,如果你想要一些阻塞,甚至是信号 (ManualResetEventSlim),但是您的要求表明您想要非阻塞。

要继续执行或向 GUI 发出您的进程已完成的信号,您可以在 UI 线程上调用一些方法,如下所示:

void Success() {
  Invoke((MethodInvoker) delegate {
    SomeMethodOnTheUI();
  });
}

这基本上是一个 async/callback 策略。