【问题标题】:Do work without blocking the gui thread在不阻塞 gui 线程的情况下工作
【发布时间】:2016-01-28 16:37:47
【问题描述】:

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

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

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

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&lt;..

所以我寻找类似的东西:

  1. 创建一个以动作为参数的线程
  2. 从线程返回值
  3. 结束话题

【问题讨论】:

  • 库是否提供使用Asynchronous Programming Model(又名BeginInvokeEndInvoke)的方法?您使用的是 .Net 4.5 或更高版本吗?你看过continuations吗?我们真的需要更多地了解您的开发环境来帮助解决这个问题。

标签: c# multithreading asynchronous


【解决方案1】:

尝试强制使用新线程(或 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();

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

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

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

这基本上是一种异步/回调策略。

【讨论】:

  • 请注意,OP 的问题与启动线程无关,而是与等待结果的错误方式有关(UI 线程上的.Result)。所以除非你解释神奇的Success() 功能(包括Invoke),否则我认为这对 OP 没有帮助。
猜你喜欢
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2015-11-17
  • 2020-11-08
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
相关资源
最近更新 更多