我已经完成了这个问题,但没有帮助.
这里的情况不同.我正在使用Backgroundworkers.第一个backgroundworker开始操作用户的图像输入和firstbackgroundworker_runworkercompleted()我正在使用调用其他3个后台工作者
algo1backgroundworker.RunWorkerAsync();
algo2backgroundworker.RunWorkerAsync();
algo3backgroundworker.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)
这是每个的代码:
algo1backgroundworker_DoWork()
{
Image img = this.picturebox.Image;
imgclone = img.clone();
//operate on imgclone and output it
}
algo2backgroundworker_DoWork()
{
Image img = this.picturebox.Image;
imgclone = img.clone();
//operate on imgclone and output it
}
Run Code Online (Sandbox Code Playgroud)
类似的操作在其他algo*backgrougrondworker_doWork()中完成.
现在有时我得到"InvalidOperationException - 对象目前正在其他地方使用".它很随意.我有时会在algo1backgroundworker_DoWork中获取此信息,有时在algo2backgroundworker_DoWork中,有时在Application.Run(new myWindowsForm())中获取;
我不知道发生了什么事.
我的C#应用程序有几个后台工作者.有时候一个后台工作人员会开火.当第一个后台工作程序完成并RunWorkerCompleted触发事件时,该事件将触发哪个线程,UI或从中RunWorkerAsync调用的第一个后台工作程序?我使用的是Microsoft Visual C#2008 Express Edition.任何您可能有的想法或建议将不胜感激.谢谢.
我正在创建一个自动测试运行应用程序.在这部分应用程序中,我正在研究一个轮询服务器.它的工作原理是不断轮询Web服务器,以确定何时应运行新的自动化测试(对于我们的GUI应用程序的夜间自动运行).
当轮询服务器看到请求时,它会下载所需的所有信息,然后在后台工作程序中执行测试运行.问题是测试运行的一部分具有Clipboard.Clear()在后台工作线程中发生的OLE,COM和其他调用(例如).发生其中一个调用时,会发生以下异常:
在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式.确保您的Main函数标记了STAThreadAttribute.
如何将后台工作线程标记为单线程单元?我的Program.cs中的Main调用显然已经具有该属性.
我是那些偶然的程序员之一,所以我对编程最佳实践知之甚少.
我有一个目前使用4 Background Worker的应用程序.
所以我宣布他们:
private BackgroundWorker bw1;
private BackgroundWorker bw2;
private BackgroundWorker bw3;
private BackgroundWorker bw4;
Run Code Online (Sandbox Code Playgroud)
然后配置它们:
bw1 = new BackgroundWorker();
bw1.WorkerReportsProgress = true;
bw1.DoWork += new DoWorkEventHandler(bw1_DoWork);
bw1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw1_RunWorkerCompleted);
bw1.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw2 = new BackgroundWorker();
bw2.WorkerReportsProgress = true;
bw2.DoWork += new DoWorkEventHandler(bw2_DoWork);
bw2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw2_RunWorkerCompleted);
bw2.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw3 = new BackgroundWorker();
bw3.WorkerReportsProgress = true;
bw3.DoWork += new DoWorkEventHandler(bw3_DoWork);
bw3.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw3_RunWorkerCompleted);
bw3.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw4 = new BackgroundWorker();
bw4.WorkerReportsProgress …Run Code Online (Sandbox Code Playgroud) 我正在编写一个Windows服务,一旦启动就会每X小时运行一次.它完成的过程相当密集,所以我想使用后台工作程序.我正在使用设置文件来存储运行和上次运行服务之间的小时数.
我不确定最好的方法 - 也就是说,我希望服务尽可能少地使用资源,当它运行时,它需要在后台工作程序中运行,报告它做了什么,然后回到空闲模式.
我考虑过使用2名背景工作者.第一个worker是服务的私有局部变量,运行如下:
while (true)
{
//create new background worker and run
Thread.Sleep(Settings.Default.SleepTimeHours * 3600000);
}
Run Code Online (Sandbox Code Playgroud)
使用在循环的每次迭代中创建的子工作程序,并在完成时销毁.为了支持取消,我想我必须在服务中有第二个工作者的本地实例,但如果当前进程没有运行,它将为null.当辅助工作程序完成时,它将发送我的报告,在设置文件中设置上次运行时间,然后处理该工作程序并将引用设置为null.
我想知道是否有更好的方法来做这个或最好的做法.
谢谢
取消BackgroundWorker操作的方法是调用BackgroundWorker.CancelAsync():
// RUNNING IN UI THREAD
private void cancelButton_Click(object sender, EventArgs e)
{
backgroundWorker.CancelAsync();
}
Run Code Online (Sandbox Code Playgroud)
在BackgroundWorker.DoWork事件处理程序中,我们检查BackgroundWorker.CancellationPending:
// RUNNING IN WORKER THREAD
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (!backgroundWorker.CancellationPending) {
DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
上述想法遍布整个网络,包括在BackgroundWorker的MSDN页面上.
现在,我的问题是:这个线程安全怎么样?
我已经查看了ILSpy中的BackgroundWorker类 - CancelAsync()只需将cancellationPending设置为true而不使用内存屏障,CancellationPending只需返回cancellationPending而不使用内存屏障.
根据这个Jon Skeet页面,上面的内容不是线程安全的.但是BackgroundWorker.CancellationPending的文档说:"这个属性是供工作线程使用的,它应该定期检查CancellationPending并在设置为true时中止后台操作."
这里发生了什么?它是否是线程安全的?
我想在后台线程中执行的进程密集型方法调用如下所示:
object.Method(paramObj, paramObj2);
Run Code Online (Sandbox Code Playgroud)
所有这三个对象都是我创建的对象.现在,从我看到的最初示例中,您可以将对象传递给后台工作者的DoWork方法.但是,如果我需要将额外的参数传递给该对象,我应该怎么做呢,就像我在这里做的那样?我可以将它包装在一个对象中并完成它,但我认为在这个上获得别人的输入是明智的.
我在后台工作线程的已完成方法中设置对象的DataContext.出于某种原因,我收到一个错误说:
此时无法修改此节点的逻辑子节点,因为正在进行树步行指向Chart1.DataContext = allDates行.
树木行走的意义何在?我已经尝试使用Dispatcher操作执行此设置,并且出现相同的错误...任何想法?谷歌在这个错误消息上没有任何结果.
代码导致这是微软Charting工具包的内部......我想知道我是否在他们的控制中发现了一个错误......
没有Dispatcher:
void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
ArticlesPerTimePeriodResult result = (ArticlesPerTimePeriodResult)e.Result;
lvArticles.ItemsSource = result.DatesOfArticles;
Chart1.DataContext = result.AllDates;
}
Run Code Online (Sandbox Code Playgroud)
使用Dispatcher:
void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
ArticlesPerTimePeriodResult result = (ArticlesPerTimePeriodResult)e.Result;
lvArticles.ItemsSource = result.DatesOfArticles;
Dispatcher.BeginInvoke((Action<List<KeyValuePair<DateTime,int>>>)(delegate(List<KeyValuePair<DateTime,int>> allDates)
{
Chart1.DataContext = allDates;
}), result.AllDates);
//Chart1.DataContext = result.AllDates;
}
Run Code Online (Sandbox Code Playgroud)
错误:
System.Reflection.TargetInvocationException was unhandled
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, …Run Code Online (Sandbox Code Playgroud) 我有2种C#WPF应用程序项目:
所有这些都应该产生2-10个长时间运行(天)的过程,这些过程可以被用户取消和重新启动.
我有兴趣遵循最佳设计实践.首先,现在,我有兴趣消除BackgroundWorker使用的歧义,但我希望,我的问题应该对其他异步模式有效.
我看到(矛盾)并发的观点
异步模式:
A).NET 4.5使它们过时了
"基于异步的异步编程方法几乎在所有情况下都优于现有方法.特别是,对于IO绑定操作,这种方法优于BackgroundWorker,因为代码更简单,您不必防范竞争条件.与Task.Run结合使用,异步编程优于 BackgroundWorker用于CPU绑定操作,因为异步编程将运行代码的协调细节与Task.Run传输到线程池的工作分开"
BackgroundWorker)在.NET 4.5中没有过时 我仍有疑问:
如果它们在.NET 4.5中已经过时,为什么它们在.NET 4.0中不会过时?
2A)我是否错误地理解.NET 4.0新功能在.NET 4.0中仍然"易于"实现/重现?
从旧版 .NET Framework 迁移,我需要创建一个长时间的后台进程工作者。
查看文档我发现了一个BackgroundService类,用于这种目的。但是我偶然发现了两种相同的(就我的观点而言)方法ExecuteAsync()和StartAsync()
有人可以向我解释它们之间的主要区别吗?是不是某种隔离原则——我们有一种将数据设置为“构造函数”的方法,我们有一种实际做事的方法?
backgroundworker ×10
c# ×10
.net ×3
wpf ×2
.net-core ×1
async-await ×1
clipboard ×1
events ×1
migration ×1
parameters ×1
sta ×1
winforms ×1