Tag: multithreading

等待很长的过程并仍在更新UI

我一直在尝试创建一个写入数据库的任务,而不会阻塞UI线程。 我遇到的最大问题是等待该过程完成而不会发生阻塞。 我一直在努力避免使用DoEvents (虽然它现在经常通过这个程序使用,我想在前进时不再使用它)。 我试图创建进程以在第二个线程上运行并等待它完成以及使用BackgroundWorker 。 我遇到的问题不是代码在不同的线程中运行,而是试图找到一种等待它完成的方法。 基本上,现在我做以下事情: 连接到数据库 创建一个后台工作者(或线程)来写入数据库(我可能最终会使用BackgroundWorker所以我可以使用ReportProgress 启动线程或BackgroundWorker 使用While循环等待线程/ BackgroundWorker完成。 对于线程,我等待IsAlive变为false,对于BackgroundWorker ,我切换一个布尔变量。 我让用户知道过程已经完成。 问题在于#4。 执行一个没有代码的while循环,或Thread.Sleep(0)使UI被阻止( Thread.Sleep(0)使程序也占用100%的程序资源) 所以我这样做: while (!thread.IsAlive) Thread.Sleep(1); -要么- while (bProcessIsRunning) Thread.Sleep(1); 它会阻止UI。 如果我在那里调用Application.DoEvents() ,UI会更新(虽然它是可点击的,所以我必须在此过程运行时禁用整个表单)。 如果我同步运行该进程,我仍然需要创建某种方式来更新UI(在我看来,一个DoEvents调用),所以它似乎没有被锁定。 我究竟做错了什么?

C#是否可以中断ThreadPool中的特定线程?

假设我在ThreadPool排队了一个工作项,但是如果没有要处理的数据,则工作项会阻塞(从BlockingQueue读取)。 如果队列为空并且没有更多的工作进入队列,那么如果我想中断阻塞任务,我必须调用Thread.Interrupt方法,但是如何使用ThreadPool做同样的事情? 代码可能如下所示: void Run() { try { while(true) { blockingQueue.Dequeue(); doSomething(); } } finally { countDownLatch.Signal(); } } 我知道在这种情况下最好的办法是使用常规的Thread ,但我想知道是否有一个ThreadPool等效方法来中断工作项。

当你在C#任务awaiter上调用`OnCompleted()`时,你如何等待OnCompleted调用中给出的新作业?

我的Controller对象使用Renci.SshNet通过SSH调用MySQL数据库,因为我连接到几个DB,我转向multithreading,函数af.FetchAll()返回一个DataSet ,所有这些都被添加到一个列表DataList ,然后我要求完成所有任务,然后我将我的DataList给writer对象以将其保存到CSV文件,问题是: awaiter.OnCompleted(() =>..etc内部的代码仍在更新尽管我要求任务完成foreach (Task t in taskList) t.Wait();器试图访问它时的DataList ,我怎样才能确保awaiter在继续执行之前完成执行并写入’ DataList’到文件 public void Query() { List QueriesList = quryValLister.GetQueriesList(); List ConnectionsList = concValLister.GetConnectionList(); // iterating over servers List taskList = new List(); foreach (ConnectionValues obj in ConnectionsList) { Controller af = new Controller(obj, QueriesList); Task taskDataResult = Task.Run (() => af.FetchAll()); taskList.Add(taskDataResult); var awaiter […]

跨线程UI组件调用

这是处理跨线程操作的适当方法吗? 我应该使用新的属性名称,例如“EditValueThreadSafe”而不是覆盖“EditValue”吗? 我不认为EditValue的实现发生了变化,因为无论如何调用基本属性。 namespace MyApplication.Components { using System.Windows.Forms; /// /// Thread-safe implementation of the DevExpress.XtraEditors.ComboBoxEdit class. /// public class ComboBoxEditThreadSafe : DevExpress.XtraEditors.ComboBoxEdit { /// /// Gets or sets the edit value. /// /// The edit value. public override object EditValue { get { return base.EditValue; } set { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(delegate { this.SetEditValue(value); […]

TaskFactory.Tasks中BlockingCollection.GetConsumingEnumerable()集合的Parallel.ForEach和foreach循环

我已经尝试了这两个循环,并注意到即使Task的Action委托中的常规foreach循环应该并行执行,它也不会并行处理元素。 但是,如果我用Parallel.ForEach替换它,我会看到数据正在跨多个线程并行处理。 代码1: Task loadingTask1 = Factory.StartNew(() => { foreach (MyOneClass dg in Queue.GetConsumingEnumerable()) { MyOtherClass vl = new MyOtherClass(); vl.Id = dg.Id; vl.PerformTimeConsumingAction(); OutputQueue.Add(vl); } }); 代码2: Task loadingTask2 = Factory.StartNew(() => { Parallel.ForEach(Queue.GetConsumingEnumerable(), (dg) => { MyOtherClass vl = new MyOtherClass(); vl.Id = dg.Id; vl.PerformTimeConsumingAction(); OutputQueue.Add(vl); }); }); 在每次迭代时使用Console.Write语句运行的代码1似乎等待上一个循环完成,直到它抓住下一个循环,但代码2确实并行处理多个元素。 我是否正确理解Task.Action中的常规foreach? 我认为.NET将启动尽可能多的任务线程作为加载保证,并且每个迭代的foreach将被并行处理。 我也尝试将PLINQ结果传递给上述两个代码和观察者相同的行为:常规foreach似乎等待上一次迭代完成以启动下一个代码,即使我使用过.AsParallel()和.WithExecutionMode(ParallelExecutionMode.ForceParallelism)指令。 任何见解都将受到高度赞赏。 […]

从另一个线程读取Checkbox状态

我试图从WPF中的BackgroundWorker中读取复选框的值: 这不起作用: bool? isSleepChecked = checkBoxSleep.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate{ return checkBoxSleep.IsChecked;}); 无法将匿名方法转换为委托类型’System.Threading.ThreadStart’,因为块中的某些返回类型不能隐式转换为委托返回类型 编辑 – 这是HB的答案,使用委托而不是lambda表达,我发现它更具可读性 bool? isSleepChecked = (bool?)checkBoxSleep.Dispatcher.Invoke(new Func(delegate { return checkBoxSleep.IsChecked; }));

从SynchonizationContext派生

简而言之,我已经实现了一个派生自SynchronizationContext的类,以便GUI应用程序可以轻松使用在GUI线程以外的线程上引发的事件。 我非常感谢对我的实施的评论。 具体来说,你有什么建议反对或可能导致我没有预料到的问题吗? 我最初的测试成功了。 长版本:我目前正在开发分布式系统(WCF)的业务层,它使用回调将事件从服务器传播到客户端。 我的设计目标之一是提供可绑定的业务对象(即INotifyPropertyChanged / IEditableObject等),以便在客户端轻松使用这些对象。 作为其中的一部分,我提供了回调接口的实现,该接口在事件进入时处理事件,更新业务对象,进而引发属性更改事件。 因此,我需要在GUI线程上引发这些事件(以避免跨线程操作exception)。 因此,我尝试提供自定义SynchronizationContext,实现回调接口的类使用它来将事件传播到GUI线程。 此外,我希望此实现独立于客户端环境 – 例如WinForms GUI应用程序或ConsoleApp或其他东西。 换句话说,我不想假设静态SynchronizationContext.Current可用。 因此我使用ExecutionContext作为后备策略。 public class ImplicitSynchronisationContext : SynchronizationContext { private readonly ExecutionContext m_ExecContext; private readonly SynchronizationContext m_SyncContext; public ImplicitSynchronisationContext() { // Default to the current sync context if available. if (SynchronizationContext.Current != null) { m_SyncContext = SynchronizationContext.Current; } else { m_ExecContext […]

每个查询的新sql连接?

我正在编写一个与本地sql server通信的服务器应用程序。 每个客户端都需要读取或写入数据库。 拥有一个可以在单个sql连接上排队并执行sql命令的线程安全类会更好吗? 或者我应该为每个命令打开一个新连接? 性能是否重要?

如何从另一个线程锁定方法的一部分?

如何从另一个线程中锁定c#中的一部分方法? 我的意思是如果其中一个线程在这里,然后退出…例如: if(threads[0].WasHere) { return; }

如何在不需要等待当前函数/线程的结果的情况下运行异步任务?

有没有机会避免等待? 我们想要的例子: async Task SomeTask() { await ChildTask(); //Then something we want to be done without waiting till “Child Task” finished OtherWork(); } async Task ChildTask() { //some hard work }