- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在过去使用 BackgroundWorker 时遇到过此类问题,但我想使用 .NET 4.5 的新异步/等待方法。我可能找错人了。请指教。
目标:创建一个组件,该组件将执行一些长时间运行的工作,并在执行工作时显示带有进度条的模态表单。该组件将获取一个窗口的句柄,以在执行长时间运行的工作时阻止交互。
状态:见下面的代码。在我尝试与 window 互动之前,我认为我做得很好。如果我放任不管(即不要触摸!),一切都会“完美”运行,但如果我只是点击任一窗口,程序就会在长时间运行的工作结束后挂起。实际交互(拖动)将被忽略,就好像 UI 线程被阻止一样。
问题:我的代码可以很容易地修复吗?如果是这样,如何?或者,我应该使用不同的方法(例如 BackgroundWorker)吗?
代码(Form1 是一个带有 ProgressBar 和一个公共(public)方法 UpdateProgress 的标准表单,它设置 ProgressBar 的值):
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting..");
var mgr = new Manager();
mgr.GoAsync();
Console.WriteLine("..Ended");
Console.ReadKey();
}
}
class Manager
{
private static Form1 _progressForm;
public async void GoAsync()
{
var owner = new Win32Window(Process.GetCurrentProcess().MainWindowHandle);
_progressForm = new Form1();
_progressForm.Show(owner);
await Go();
_progressForm.Hide();
}
private async Task<bool> Go()
{
var job = new LongJob();
job.OnProgress += job_OnProgress;
job.Spin();
return true;
}
void job_OnProgress(int percent)
{
_progressForm.UpdateProgress(percent);
}
}
class LongJob
{
public event Progressed OnProgress;
public delegate void Progressed(int percent);
public void Spin()
{
for (var i = 1; i <= 100; i++)
{
Thread.Sleep(25);
if (OnProgress != null)
{
OnProgress(i);
}
}
}
}
class Win32Window : IWin32Window
{
private readonly IntPtr _hwnd;
public Win32Window(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get
{
return _hwnd;
}
}
}
}
最佳答案
async
和 await
关键字并不意味着“在后台线程上运行”。我有一个 async
/ await
intro on my blog描述他们做的意思。您必须明确地将 CPU 绑定(bind)操作放在后台线程上,例如 Task.Run
.
另外,Task-based Asynchronous Pattern文档描述了 async
的常用方法代码,例如进度报告。
class Manager
{
private static Form1 _progressForm;
public async Task GoAsync()
{
var owner = new Win32Window(Process.GetCurrentProcess().MainWindowHandle);
_progressForm = new Form1();
_progressForm.Show(owner);
var progress = new Progress<int>(value => _progressForm.UpdateProgress(value));
await Go(progress);
_progressForm.Hide();
}
private Task<bool> Go(IProgress<int> progress)
{
return Task.Run(() =>
{
var job = new LongJob();
job.Spin(progress);
return true;
});
}
}
class LongJob
{
public void Spin(IProgress<int> progress)
{
for (var i = 1; i <= 100; i++)
{
Thread.Sleep(25);
if (progress != null)
{
progress.Report(i);
}
}
}
}
请注意 Progress<T>
type 正确处理线程编码(marshal)处理,因此不需要在 Form1.UpdateProgress
中进行编码(marshal)处理.
关于c# - 使用 WinForms ProgressBar 异步/等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17972268/
我的应用程序中有一个 ProgressBar 小部件,无论我做什么,它总是显示为粗橙色(2.x 样式)而不是细蓝色(4.x 样式) . 项目构建目标设置为 Google API 4.0.3(API 级
private static ProgressDialog pDialog; pDialog = new ProgressDialog(activity); pDialog.setIndetermin
我试图让 TalkBack 阅读进度条上的进度,但运气不佳。关于如何获取该信息以便 TalkBack 可以说出来的任何想法。 谢谢 公共(public)类 MainActivity 扩展 Activi
进度条总是返回null public void calcola(View view) { final Dialog myDialog = new Dialog(this);
我正在尝试用选取框样式测试进度条,但没有成功 private void Form1_Load(object sender, EventArgs e) { Applica
我使用以下 Ruby 片段下载 a 8.9MB file . require 'open-uri' require 'net/http' require 'uri' def http_download
我为操作栏按钮尝试了两种不同的进度条样式,通过 refreshMenuItem.setActionView(R.layout.actionbar_indeterminate_progress); ac
每当我输入 fragment 时,我都会看到几秒钟的空白,然后 WebView 中的网页就会出现。 ProgressBar 好像没有显示。 这是我的 XML 文件,用于 WebView 和 Progr
我的包依赖于一个名为 progressbar 的包。有一个bug in progressbar 2.3导致Python>3.3安装失败,因此我安装了latest git repo from this
任何默认的 ProgressBar 都有一个 ClipDrawable 级别,例如,一个绿色的 Drawable 在我的设备上填充灰色背景,在其他设备上填充黄色。 我的问题:当进度小于最大值时,是否可
这是随意的原型(prototype)代码,因此我尝试了我认为应该有效的方法,如果没有,则在谷歌上搜索,然后在仔细阅读类似问题后在这里提问。 我的 Shell 中有以下标记看法:
要在执行查询时显示 ProgressBar,我使用以下代码: if not Query1.Prepared then Query1.Prepare; Query1.Open; ProgressBa
我有三个类,例如 View 、逻辑、 Controller 。 class View{ Progressbutton pb; void start animation(){
我正在用 C#/WPF(.Net 框架 4.0)编写一个应用程序。我遇到的一件事是如何在应用程序非常繁忙时更新控件(如果可能)。我想我只是在努力尝试我在网上找到的东西来让它工作(而且在极少数情况下它会
要在执行查询时显示 ProgressBar,我使用以下代码: if not Query1.Prepared then Query1.Prepare; Query1.Open; ProgressBa
已关闭。此问题不符合 Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 已关闭 3 年前。 奥 git _a
我创建了一个 ping 程序来 ping 5 服务器。如何在进度运行时让进度条运行。当 ping 完成时,进度条将为 100% private void btnGetstatusActionPer
我想在流程完成后在 PrimeFaces 上隐藏一个进度条。我认为没有必要在不工作时显示进度条。 html代码:
我想添加JProgressBar,它将在下载文件的程序中填充。 第三个问题是如何使进度条在 setValue 中添加正确的金额(例如:当它下载最后一个文件时,JPB 将完成)。 请注意,要下载的文件数
给定一个变量 N,反射(reflect)秒数,我想要一个 jQueryUI Progressbar顺利地从空更新到反射(reflect)该时间段内的完成。 换句话说,我想要一个显示进度条的functi
我是一名优秀的程序员,十分优秀!