如何在c#中正确实现等待异步[重复]

Posted

技术标签:

【中文标题】如何在c#中正确实现等待异步[重复]【英文标题】:How to proper implement await async in c# [duplicate] 【发布时间】:2018-11-12 16:37:18 【问题描述】:

我是 C# 新手,并且 我正在尝试在 C# 中使用 asyncawait 函数来处理线程和非阻塞 GUI。

这是我目前所拥有的:

 public async Task ReadInfo()
        
            string serial;
            android.UpdateDeviceList();
            if (android.HasConnectedDevices)
            
                serial = android.ConnectedDevices[0];
                device = android.GetConnectedDevice(serial);
                string model = device.BuildProp.GetProp("ro.product.model");
                string bootloader = device.BuildProp.GetProp("ro.bootloader");
                string pda = device.BuildProp.GetProp("ro.build.PDA");

                addlog("Model : " , Color.White, true, true);
                addlog(model, Color.DodgerBlue, true, false); 
                addlog("Bootloader : ", Color.White, true, true);
                addlog(bootloader, Color.DodgerBlue, true, false); 
                addlog("PDA Version : ", Color.White, true, true);
                addlog(pda, Color.DodgerBlue, true, false); 
            
            else
            
                addlog("ADB device not found.", Color.Red, true, true);
            

        

这是 AddLog 方法:

public void addlog(string s, Color color, bool isBold, bool newline = false)
        
            if (newline)
            
                rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.AppendText("\r\n")));
            
            Color selectionColor = color;
            rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.SelectionStart = rtbLog.Text.Length));
            rtbLog.BeginInvoke(new MethodInvoker(() => selectionColor = rtbLog.SelectionColor));
            rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.SelectionColor = color));
            if (isBold)
            
                rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.SelectionFont = new Font(rtbLog.Font, FontStyle.Bold)));
            
            rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.AppendText(s)));
            rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.SelectionColor = selectionColor));
            rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.SelectionFont = new Font(rtbLog.Font, FontStyle.Regular)));
            rtbLog.BeginInvoke(new MethodInvoker(() => rtbLog.ScrollToCaret()));
        

在 Button1_Click 我有这个:

 private async void Button1_Click(object sender, EventArgs e)
        
           await  ReadInfo();
        

我不知道为什么它会冻结 GUI。

解决问题

变化

public async Task ReadInfo()

 public void ReadInfo()

并以 button1_click 的身份调用

Task.Run(() => ReadInfo());

【问题讨论】:

使用asyncawait 不会神奇地为您创建新线程。此外,由于ReadInfo 上没有单个await,因此整个方法同步运行。我建议您开始使用官方文档:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… 什么是rtbLog,你为什么要在BeginInvokeMethodInvoker 上设置属性? 跨线程调用。 我建议您将ReadInfo public void ReadInfo 并将您的按钮点击更改为await Task.Run(() => ReadInfo());。这应该注意不冻结 GUI 并保持代码干净 @CamiloTerevinto 感谢您将其简化为我所期望的答案 【参考方案1】:

ReadInfo 中的任何内容实际上都不是异步的——事实上,编译器应该已经警告过你了。如果没有异步 incomplete 等待,则一切都在当前线程 - UI 线程上继续。

添加async不会使代码在不同的线程上运行。

【讨论】:

@CamiloTerevinto 甚至 await 都没有明确添加任何线程。在这种情况下,我希望应用同步上下文,因此await 是对 UI 线程的回调无论如何 这种场景下如何实现新线程? @AmanAli 如果您想使用线程:使用线程 - ThreadThreadPool.QueueUserWorkItemTask.Run 中的任何一个都应该是不错的候选者 是的,我知道。但令人敬畏的是人们不阅读该方法将同步运行的警告。 我没有看到任何警告。

以上是关于如何在c#中正确实现等待异步[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 c# 应用程序中正确保护 api 凭据

如何在python的类中正确实现辅助函数

在这种情况下,如何在 Flutter 中正确实现 FutureBuilder?

如何在php中正确实现结构化菜单

ios - 如何在 ios swift 中正确实现后台获取

如何在 Keras 中正确实现自定义活动正则化器?