- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码从后台 worker 更新我的进度条和状态栏。我运行同一个后台工作程序两次。我第一次运行它时,我从 MainWindow 构造函数中调用它,它工作正常。在构造函数的末尾,我设置了一个计时器以每隔一段时间调用该方法。
System.Threading.TimerCallback timerCallback = new System.Threading.TimerCallback(RefreshWebDataTimer);
timer = new System.Threading.Timer(
timerCallback, null,
Dictionary.MS_TIMER_FIRSTREFRESH_PERIOD,
Dictionary.MS_TIMER_REFRESH_PERIOD);
当从计时器调用它时,出现以下错误:
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll Additional information: The calling thread cannot access this object because a different thread owns it.
我添加了一些调试,实际上 Dispatcher Thread 与计时器在不同的线程上,与原始运行在同一线程上。
private void backgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
System.Diagnostics.Debug.Print("Current Thread: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Diagnostics.Debug.Print("Dispatcher Thread: {0}", progressBar.Dispatcher.Thread.ManagedThreadId);
this.progressBar.Visibility = Visibility.Visible;
this.progressBar.Value = e.ProgressPercentage;
if (e.UserState != null)
{
this.statusBar.Text = e.UserState.ToString();
}
}
Current Thread: 22 Dispatcher Thread: 7
我的印象是 ProgressChanged
和 RunWorkerCompleted
事件总是在主 UI 线程上运行,以解决这个问题并能够进行 UI 更新。显然,我误解了这里发生的事情。
我更新了我的解决方案以使用 Dispatcher,如下所示:
private void backgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
progressBar.Dispatcher.BeginInvoke(new OneArgIntDelegate(updateProgressBar), e.ProgressPercentage);
if (e.UserState != null)
{
progressBar.Dispatcher.BeginInvoke(new OneArgStrDelegate(updateStatusBar), e.UserState.ToString());
}
}
private void updateStatusBar(string Text)
{
this.statusBar.Text = Text;
}
private void updateProgressBar(int ProgressPercentage)
{
this.progressBar.Visibility = Visibility.Visible;
this.progressBar.Value = ProgressPercentage;
}
此解决方案有效,但我认为 BackgroundWorker 的全部意义在于我不必执行此操作。有人可以解释我不正确的假设以及到底发生了什么。有没有办法通过以不同方式设置计时器来在没有调度程序的情况下执行此操作?
谢谢,
哈里森
最佳答案
I was under the impression that the ProgressChanged and RunWorkerCompleted events always ran on the main UI thread in order to solve this problem and be able to do UI updates. Apparently, I misunderstand what is going on here.
BackgroundWorkers ProgressChanged 被回调到拥有 BackroundWorker 的线程,这并没有离开 UI 线程,当您第二次创建 BackgroundWorker
时,它是在另一个线程上创建的,因此 ProgressChanged
将在创建 BackgroundWorker
的线程上调用,在本例中为计时器线程。
您可以从 Timer
调用 RefreshWebDataTimer
到 UI 线程,或者使用 DispatcherTimer
来确保 RefreshWebDataTimer
在 UI 线程上被调用。
选项 1:
timer = new System.Threading.Timer(
(o) => Dispatcher.Invoke((Action)RefreshWebDataTimer),
null,
Dictionary.MS_TIMER_FIRSTREFRESH_PERIOD,
Dictionary.MS_TIMER_REFRESH_PERIOD);
选项 2:
timer = new DispatcherTimer(
TimeSpan.FromSeconds(1),
DispatcherPriority.Background,
(s, e) => RefreshWebDataTimer(),
Dispatcher);
关于c# - BackgroundWorker.ProgressChanged 事件不在调度程序线程上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18709532/
在我的应用程序中,我在添加到我的列表框之前通过打开的 Wireshark 进程检查我的文件。这是添加目录单击事件,它获取根文件夹并检查此文件夹和子文件夹中的所有文件: private void btn
我有一个使用异步后台工作程序执行批处理文件的程序。这是代码: public static void Execute(CmdObj obj, bool batch) { CmdObj = obj
我正在尝试在项目中执行数据库密集型任务。这是一个演练: 我们需要搜索我们的 worker 数据库,我们称之为 Locums,并找到一个适合特定工作的人。当我们决定处理 x 个作业时,此过程开始。因此,
首先,我还是个初学者,如果您能耐心一点,我将不胜感激:) 今天我一直在为这件事绞尽脑汁。 问题是,我想运行三个不同的后台程序。但是我想等到一个运行完再运行下一个,依此类推。 每个后台 worker 都
我需要确保 BackgroundWoker 在被调用之前不忙,所以我检查 IsBusy 并调用 CancelAsync如果是: if (bgWorker.IsBusy)
我的目标是: 用户在组合框中输入完整或部分计算机名 按钮单击事件启动后台工作程序将计算机名传递给 DoWork 方法 DoWork 方法在 ActiveDirectory 中搜索计算机名并将集合传递给
每次我的代码需要与网络或数据库通信时,我都会使用后台工作人员,我是否可以使用太多,执行这些任务的正确方法是什么? 如果我不使用后台工作程序,则在远程主机关闭等情况下,gui会锁定,因此使用后台工作程序
关于 BGW 长期运行的任何想法建议? 最佳答案 是的 :)。在 BackgroundWorker 或 ThreadPool 中进行长时间运行的操作并没有本质上的错误……如果由于长时间运行的操作而导致
学习构建多线程 WPF 应用程序我读到了一些使用 BackgroundWorker 的限制,这对我来说不是很清楚。请帮我理解: 如果我不仅想要一个线程在 UI 的幕后工作,而且可能有多个线程,它们彼此
问题:重新使用 .NET Backgroundworker,有没有办法让异常正常传递回主线程? 背景: 目前在我的 WinForms 应用程序中,我有通用异常句柄,如果(a)自定义应用程序异常然后呈现
在尝试实现一个简单的 BackgroundWorker 时,我遇到了臭名昭著的“跨线程操作无效”异常。我花了几个小时阅读我能找到的关于这个主题的所有内容,包括关于 SO 的许多相关问题,但我就是不明白
有没有办法缩短我的 BackgroundWorker.CancellationPending 检查点? 例如,有没有办法像下面的示例代码一样封装return: //REAL CODE (CURRENT
嗨,我在处理完成后,无法将在BackgroundWorker的DoWork处理程序内部生成的图像数据分配给图像对象。我收到一条错误消息,指出“调用线程无法访问此对象,因为其他线程拥有它”。错误行是 P
如何获得有意义的BackgroundWorker.Error当DoWork必须调用可能引发异常的委托(delegate)? 我正在实现一个静态 MsgBox公开向用户传达自定义消息的各种方式(使用自定
我知道您可以在首次启动 backgroundworker 时通过 RunWorkerAsync 函数调用传递参数,但是您可以在它已经启动后向它传递数据吗?或者我是否需要创建自己的并发形式来处理从不同线
我有一个风格问题,关于我应该在 Windows 窗体应用程序上使用的后台线程实现的选择。目前,我的表单上有一个 BackgroundWorker,它具有无限 (while(true)) 循环。在此循环
我正在尝试在 .NET 1.1 中实现一个 BackgroundWorker(因为没有任何东西),而且我不太精通线程和委托(delegate)。 现在我有一个名为 BackgroundWorker 的
foreach (string file in listToConvert) { BackgroundWorker backgroundWorker = new BackgroundWorke
我正在制作我的第一个 C# GUI。它使用 BackgroundWorker 来运行计算量大的模拟。模拟会定期报告(通过 ProgressChanged 事件)需要在 GUI 中显示的大量信息。 GU
我想从一个表单启动一个后台 worker 。 private void button2_Click(object sender, EventArgs e) { back
我是一名优秀的程序员,十分优秀!