我在 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 中是红色标志。
森林海
TA贡献2011条经验 获得超2个赞
awaitTask.Run(() => resetEvent.WaitOne());
应该可以解决问题。ManualResetEvent
不可等待,不能直接在其上使用 await 关键字,因此您需要将其包装在任务中
- 2 回答
- 0 关注
- 221 浏览
添加回答
举报
0/150
提交
取消