求助一个异步编程的具体问题

GoingNaive 2014-10-06 07:45:14
已知我有一个同步方法public bool Login(string username, string password),该方法可能需要耗费数秒,成功就返回true,失败则返回false。我想在WinForm中调用这个方法,希望不要阻塞UI线程,同时希望方法返回后在界面上显示状态。

我知道可以用事件来通知其他人方法执行完成。但是我正在学习使用async/await的使用,想使用它来完成目标,于是我将Login方法包装了一层:
public async Task<bool> LoginAsync(string userid, string password)
{
return await Task.Factory.StartNew(() => Login(userid, password));
}

现在问题来了,挖掘机。。。其实真正的问题是,我在UI线程那边应该做什么?怎样可以恰到好处地知道LoginAsync执行完成,并且取得返回值?我不能await,要不然又把UI卡住了。正确的做法应该是什么呢?

谢谢!
...全文
289 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
vbfool 2014-10-11
  • 打赏
  • 举报
回复
async/await并没有什么奢侈阻碍吧? await开始之后的部分实际上都被转移到新线程上去了。它就是把回调嵌套,变成了编写时顺序的样子。
jy251 2014-10-07
  • 打赏
  • 举报
回复
我还在用3.5.。。。。5.0暂时还没用上,但是我看了下await 和async,感觉就是ms让我们的编程中少用几个delegate而已,写法上发生了变化。 async修饰的函数,更像是一个callback,只不过这个callback是不需要你额外写什么begininvoke的。 你写的caller函数,其实第一句话就是调用了一个回调函数,第二句话,我没查过continuewith的意思,但是我从你写的代码方式看得出来,continuewith其实就是等待async的执行完毕,然后继续执行下面的代码。 你这样写的话,会导致当前线程挂起,如果是主线程的话,那么就卡UI了。 异步编程方式的话,假如你有一个login的函数,这个函数是一个异步函数,那么你在主线程中调用了这个异步函数,你想要达到异步效果的话,你就永远别在主线程中等待他的返回。你应该在异步函数中执行你的login操作全过程。
GoingNaive 2014-10-06
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
可要 --> 可以 async/await 并不是真正合理的并发,而是一种阻塞调用线程的“奢侈”并发。它告诉你“你的流程中必须用一个阻塞语句await来等待返回值”,这不是真正的并发程序设计之道。 灵活的并发设计,应该以“回调”为新的流程的“起点”,在流程设计时不需要依赖于“阻塞”逻辑。特别是当你使用全面需要并发程序时,例如你的游戏程序,或者其它的每秒产生几百个后台交互的程序时,你从设计之初就应该采用真正的并发设计流程来保证高效率。流程中总是考虑阻塞,你就根本不会设计好的并发程序,因为你满脑子还是原来顺序流程的设计习惯。因此 async/await 其实是有害的。
谢谢大牛回复,我明白了使用回调函数的重要性。 不过我有一个想法,就是如果重新定义方法成public void Login(string username, string password, Action<bool> callback),会不会不够灵活,比如说我有时候就想同步,有时候想异步,但是对返回值不感兴趣。 我在想,不要把callback作为Login的一个参数,而是由外部调用者来决定做什么会不会更好,例如

public async Task<bool> LoginAsync(string userid, string password)
{
    return await Task.Factory.StartNew(() => Login(userid, password));
}

public void Caller()
{
    bool retval = await LoginAsync(...)
    bool retval = LoginAsync(...).ContinueWith(task => { ... });
}
这样调用者想同步异步皆可,这种实现大牛觉得如何?
  • 打赏
  • 举报
回复
可要 --> 可以 async/await 并不是真正合理的并发,而是一种阻塞调用线程的“奢侈”并发。它告诉你“你的流程中必须用一个阻塞语句await来等待返回值”,这不是真正的并发程序设计之道。 灵活的并发设计,应该以“回调”为新的流程的“起点”,在流程设计时不需要依赖于“阻塞”逻辑。特别是当你使用全面需要并发程序时,例如你的游戏程序,或者其它的每秒产生几百个后台交互的程序时,你从设计之初就应该采用真正的并发设计流程来保证高效率。流程中总是考虑阻塞,你就根本不会设计好的并发程序,因为你满脑子还是原来顺序流程的设计习惯。因此 async/await 其实是有害的。
  • 打赏
  • 举报
回复
你可要重新定义方法接口
public void Login(string username, string password, Action<bool> callback)
{
    .....
}
然后调用它的时候简单地写
            ThreadPool.QueueUserWorkItem(h =>
            {
                Login("abc","123", r=>{ ...... });
            });

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧