新手请教 异步编程如何实现

m0_37646670 2019-05-16 09:02:10
  
Button_print.Click += (X, Y) =>
{
(X as Button).Enabled = false;

Task.Run(async()=> {
//非常耗时的打印时间
});

(X as Button).Enabled = true;
};


我想在打印完成时,恢复按钮,不知道怎么实现同步
Task/Thread/delegate
能给我点关键代码思路吗
...全文
212 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
m0_37646670 2019-05-18
  • 打赏
  • 举报
回复
引用 8 楼 raynors 的回复:

不同业务不同处理方式吧,事件回调逻辑清晰方便维护。
实际情况我是在弄Xamarin,在C#里我写的更简单,就是new thread(invoke.new(action())),andriod里没有invoke,查了老半天资料

weixin_35107932 2019-05-17
  • 打赏
  • 举报
回复
首先你要明白打印是什么,是一个任务还是一个处理过程,如果当成一个任务来看待,那么你已经将任务的前期工作完成了不必等待后期任务,那么你只需要监测任务的完成就够了,如果你要当打印是一个处理过程,在处理过程中需要针对打印的情况做一些处理,那么建议你使用委托或者接口的形式来处理回调问题。
  • 打赏
  • 举报
回复
await 这个关键字本身就是编译器、.net 系统为我们编排的“类似于同步顺序操作语法”的异步编程回调语法。但是你要理解其异步回调的实质,理解 await 执行之前 Button_print.Click “委托操作就已经完成了”的机制,才能真正入门 await。那么要了解机制,可以先不用 await/async 写法,先直截了当写出异步回调 Button_print.Enabled = true; 的正确代码来,先搞清楚“死循环、阻塞、Sleep 这类才是异步多线程编程大忌”的概念!
  • 打赏
  • 举报
回复
类似于:
            Button_print.Click +=  (X, Y) =>
            {
                    Button_print.Enabled = false;
 
                    Task.Run(async()=> {
                        //非常耗时的打印时间
                   
                        Button_print.BeginInvoke((Action)delegate{
                               Button_print.Enabled = true;
                        });
                    });
            };
实际上,你那个写到 Task.Run(....) 外边的所谓 Enable= true 的思路是完全错误的“异步”思路。有的人说“我异步干一件事,而我傻等这件事儿完成之后才.......”这其实就是幼稚地没学过事件驱动、异步设计概念的结果。 异步编程就是是先注册回调委托,然后在异步的那个动做完成之后自动执行。而不是什么“死循环、傻等”。
raynors 2019-05-17
  • 打赏
  • 举报
回复
SP神仙很活跃,但我看他就是纯属捣乱的,我也提问过几个帖子,一般就是披头盖脸的说你这里不规范,那里概念错误,就是不出解决方案。要么就是书读死了,要么就是大项目做多了。

就是一个用线程解决UI卡死的经典问题。

只要涉及到线程,不管你是什么同步异步,都是更新UI。就会触发一个线程间调用的错误(扯什么回调,回调难道就不是线程间调用了?)


button1.Click += (X, Y) =>
{
(X as Button).Enabled = false;

Task.Run(new Action(()=>
{
myPrintTask();
myPrintTaskDone(X);
}));
};

private void myPrintTask()
{
Thread.Sleep(2000);
}

private void myPrintTaskDone(object sender)
{
(sender as Button).Invoke(new Action(() =>{
(sender as Button).Enabled = true;
}) );
}


一般还有什么 if (this.InvokeRequired),说实话,我知道这个判断是干什么的,但不知道这个判断有什么鸟用。直接简单粗暴的Invoke了也没出过什么问题。

至于搂主所说的BEGININVOKE,你这是在更新UI的调用上,又开了一个异步线程,在这个场合上,没必要。
秋的红果实 2019-05-17
  • 打赏
  • 举报
回复

Button_print.Click +=  async(X, Y) =>
            {
                    (X as Button).Enabled = false;
 
                    await Task.Run(()=> {
                    //非常耗时的打印时间
                    Thread.Sleep(5000);
                    });
                 
                    (X as Button).Enabled = true;
            };

m0_37646670 2019-05-17
  • 打赏
  • 举报
回复
引用 5 楼 以专业开发人员为伍 的回复:
await 这个关键字本身就是编译器、.net 系统为我们编排的“类似于同步顺序操作语法”的异步编程回调语法。但是你要理解其异步回调的实质,理解 await 执行之前 Button_print.Click “委托操作就已经完成了”的机制,才能真正入门 await。那么要了解机制,可以先不用 await/async 写法,先直截了当写出异步回调 Button_print.Enabled = true; 的正确代码来,先搞清楚“死循环、阻塞、Sleep 这类才是异步多线程编程大忌”的概念!


我试试用BEGININVOKE写写看
  • 打赏
  • 举报
回复
你可以在打印完成事件中去触发回调委托就可以了。
eaqpi 2019-05-16
  • 打赏
  • 举报
回复
1、在窗体上丢一个 BackgroundWorker 控件。

2、在 BackgroundWorker1_DoWork 事件中,运行的你的耗时打印代码!并使得按钮失效。

3、在 BackgroundWorker1_RunWorkerCompleted 事件中,解开按钮锁定。
x棬===-----===-----
收工

111,098

社区成员

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

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

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