在不阻塞 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<..
。
所以我寻找类似的东西:
- 创建一个以动作作为参数的线程
- Return 来自线程的值
- 结束话题
尝试强制使用新线程(或 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 策略。
我有一个 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<..
。
所以我寻找类似的东西:
- 创建一个以动作作为参数的线程
- Return 来自线程的值
- 结束话题
尝试强制使用新线程(或 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 策略。