为了账号安全,请及时绑定邮箱和手机立即绑定

C# 需要等待线程完成而不阻塞 UI 线程

C# 需要等待线程完成而不阻塞 UI 线程

C#
繁花不似锦 2022-12-31 13:52:54
我在 UI 线程上显示 ProgressBar,然后在另一个线程上启动登录过程。这完美地工作,我得到了 ProgressBar “圆圈”,它让用户知道正在发生的事情。问题是我需要通过 UI 向用户返回任何登录错误,例如无效的用户名/密码。我更改了我的 ProgressBar 类以包含一个ErrorMessage属性,将其实例化并将其作为参数传递给登录过程。如果出现任何错误,我都会设置该ErrorMessage属性。如果它不为空,我将显示错误。if问题是登录线程在我到达检查 null之前没有完成。这都是在按钮单击事件上完成的。我的代码:MyButton_Submit.Click += async (sender, e) =>{        ManualResetEvent resetEvent = new ManualResetEvent(false);        ProgressBarHandler myprogressbar = new ProgressBarHandler(this);        myprogressbar.show();        var thread = new System.Threading.Thread(new ThreadStart(async delegate        {            await SignOn(myprogressbar);            resetEvent.Set();        }));        thread.Start();        // based on @Giorgi Chkhikvadze comment below I changed: resetEvent.WaitOne(); to:        await Task.Run(() => resetEvent.WaitOne());        // works perfectly         while (thread.ThreadState == ThreadState.Running)        {            await Task.Delay(100);        }        myprogressbar.hide();        if (myprogressbar.ErrorMesage != null)        {            Context context = Application.Context;            string text = myprogressbar.ErrorMesage ;            ToastLength duration = ToastLength.Short;            var toast = Toast.MakeText(context, text, duration);            toast.Show();        }    };}该行resetEvent.WaitOne();显然阻塞了用户界面,因为当我将其注释掉时,会显示进度条,而当我执行它时,它不会。我怎样才能解决这个问题?
查看完整描述

2 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

您不需要单独的线程;await会自己工作得很好。您也不需要ManualResetEvent将工作完成作为“信号”;使用awaiton aTask效果很好。


等效的简化代码:


MyButton_Submit.Click += async (sender, e) =>

{

  ProgressBarHandler myprogressbar = new ProgressBarHandler(this);

  myprogressbar.show();


  await SignOn(myprogressbar);

  myprogressbar.hide();


  if (myprogressbar.ErrorMesage != null)

  {

    ...

  }

};

你永远不Thread应该在 Xamarin 应用程序中输入类型。总有更简单、更好的方法。该Thread类型一般是“强黄色”标志,但在 Xamarin 中是红色标志。


查看完整回答
反对 回复 2022-12-31
?
森林海

TA贡献2011条经验 获得超2个赞

awaitTask.Run(() => resetEvent.WaitOne());应该可以解决问题。ManualResetEvent不可等待,不能直接在其上使用 await 关键字,因此您需要将其包装在任务中



查看完整回答
反对 回复 2022-12-31
  • 2 回答
  • 0 关注
  • 221 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信