Tag: multithreading

使用multithreading服务的数据库连接池

我有一个.NET 4 C#服务,它使用TPL库进行线程化。 我们最近将其切换为也使用连接池,因为一个连接正在成为处理的瓶颈。 以前,我们使用lock子句来控制连接对象的线程安全性。 当工作备份时,队列将作为任务存在,并且许multithreading(任务)将等待lock子句。 现在,在大多数情况下,线程会更快地等待数据库IO和工作进程。 但是,现在我正在使用连接池,我们遇到了一个新问题。 达到最大连接数(默认值为100)后,如果请求进一步连接,则会超时(请参阅池信息 )。 发生这种情况时,会抛出一个exception,说“连接请求超时”。 我的所有IDisposable都在using语句中,我正在管理我的连接。 这种情况的发生是由于请求的工作量超过了池可以处理的工作量(这是预期的)。 我理解为什么会抛出这个exception,并且我知道处理它的方法。 简单的重试感觉就像一个黑客。 我也意识到我可以通过连接字符串增加超时时间,但这不是一个可靠的解决方案。 在以前的设计中(没有池),工作项将因应用程序内的锁定而处理。 处理此方案以确保处理所有工作的好方法是什么?

C#线程之间的通信

我正在使用.NET 3.5,并试图解决一个问题(不是我的最高线程专家熊)。 我有一个Windows服务,它有一个非常密集的进程,一直在运行,我把这个进程放在一个单独的线程上,以便我的服务的主线程可以处理操作任务 – 即服务审计周期,处理配置更改等,等等 我通过典型的ThreadStart启动线程到一个关闭进程的方法 – 称之为workerthread。 在这个workerthread我发送数据到另一台服务器,正如预期的那样,服务器不时重新启动并且连接丢失,我需要重新建立连接(我通过事件丢失连接通知我)。 从这里我做了我的重新连接逻辑,我重新开始运行,但是我很容易注意到的事情是我每次都在反复创建这个工作线程(不是我想要的)。 现在,当我失去连接并开始新的连接时,我可以杀死它,但这似乎浪费了资源。 我真正想做的是,将调用(即我的线程启动方法)编组回到仍在内存中的线程,尽管没有做任何事情。 请发布您有用的任何示例或文档。 谢谢。

当原始类超出范围时,线程会发生什么

为了清楚起见,我简化了下面的例子,但是我在现场制作程序中遇到了这个,我看不出它会如何工作! public class Test { static void Main() { Counter foo = new Counter(); ThreadStart job = new ThreadStart(foo.Count); Thread thread = new Thread(job); thread.Start(); Console.WriteLine(“Main terminated”); } } public class Counter { public void Count() { for (int i = 0; i < 10; i++) { Console.WriteLine("Other thread: {0}", i); Thread.Sleep(500); } Console.WriteLine("Counter terminated"); […]

是“双重检查锁定是破碎”只有java的东西?

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html上的页面说,双重检查锁定在java中是有缺陷的。 我只是想知道它是否也适用于其他语言(C#,Vb,C ++等) 我读过双重检查锁定模式:是否破碎? , 这是双重检查锁定? , 如何解决Java中的“双重检查已破坏”声明? 说实话,我不知道共同的共识是什么。 有人说是的,其他人说不。 无论如何,我的问题是它是否也适用于其他语言(C#,Vb,C ++等)

线程重命名

在Java中,可以重命名线程。 在.NET中它不是。 这是因为Name是Thread类中的一次性属性: public string Name { get { return this.m_Name; } [HostProtection(SecurityAction.LinkDemand, ExternalThreading=true)] set { lock (this) { if (this.m_Name != null) { throw new InvalidOperationException(Environment.GetResourceString(“InvalidOperation_WriteOnce”)); } this.m_Name = value; InformThreadNameChangeEx(this, this.m_Name); } } } 鉴于Java允许线程重命名并且所使用的大多数底层线程结构都是在两个平台上提供操作系统,我倾向于认为我实际上可以在C#中重命名一个线程,如果我避免使用某些function)我不在乎或b)根本不使用。 你知道为什么Thread重命名是一次写入操作吗? 如果更改名称有什么想法吗? 我已经尝试过测试,我将线程重命名为: var t1 = new Thread(TestMethod); t1.Name = “abc”; t1.Start(); t1.GetType().GetField(“m_Name”, BindingFlags.Instance | BindingFlags.NonPublic).SetValue(t1, “def”); t1.GetType().GetMethod(“InformThreadNameChangeEx”, […]

你何时会使用嵌套锁定?

我正在阅读Albahari关于线程的优秀电子书,并遇到以下情况他提到“一个线程可以以嵌套(可重入)方式重复锁定同一个对象” lock (locker) lock (locker) lock (locker) { // Do something… } 以及 static readonly object _locker = new object(); static void Main() { lock (_locker) { AnotherMethod(); // We still have the lock – because locks are reentrant. } } static void AnotherMethod() { lock (_locker) { Console.WriteLine (“Another method”); } } 根据解释,任何线程都将阻塞第一个(最外层)锁定,并且只有在外部锁定退出后才会解锁。 他说“当一个方法在锁中调用另一个方法时,嵌套锁定很有用” […]

从Async回调方法与UI线程交互?

我有一个在System.Net.Sockets.NetworkStream.BeginRead完成时异步调用的方法。 skDelegate = New AsyncCallback(AddressOf skDataReceived) skStream.BeginRead(skBuffer, 0, 100000, skDelegate, New Object) 在该回调方法中,我需要与UI线程进行交互。 Sub skDataReceived(ByVal result As IAsyncResult) CType(My.Application.OpenForms.Item(“frmMain”), frmMain).refreshStats(d1, d2) End Sub 这会在方法完成后导致exception。 (当执行End Sub时) 撤消操作遇到的上下文与相应的Set操作中应用的上下文不同。 可能的原因是在线程上设置了上下文而没有恢复(撤消)。 那么我如何从回调方法中与UI线程进行交互呢? 我究竟做错了什么?

长时间运行的流程冻结UI,如何使用线程更新?

我已经为长时间运行的进程编写了此示例代码,但Windows窗体会冻结,直到该过程完成。 如何更改代码以使工作并行运行? var ui = TaskScheduler.FromCurrentSynchronizationContext(); Task t = Task.Factory.StartNew(delegate { textBox1.Text = “Enter Thread”; for (int i = 0; i < 20; i++) { //My Long Running Work } textBox1.Text = textBox1.Text + Environment.NewLine + "After Loop"; }, CancellationToken.None, TaskCreationOptions.None, ui);

使用工作线程对项目进行排队

我一直试图找出如何解决我的要求,但对于我的生活,我只是无法想出一个解决方案。 我有一个项目数据库,它们存储一种队列。 (数据库已经实现,其他进程将向此队列添加项目。) 这些项目需要大量的工作/时间来“处理”,所以我需要能够:不断地从数据库中排队项目。 对于每个项目运行一个新线程并处理该项目,然后返回true / false它已成功处理。 (这将用于将其重新添加到数据库队列中) 但是,只有当前活动线程数(每个项目正在处理一个)小于最大线程数参数时才执行此操作。 一旦达到最大线程数,我需要停止从数据库中对项目进行排队,直到当前线程数小于最大线程数。 此时它需要继续对项目进行排队。 感觉这应该是我能想到的东西,但它不是来找我。 澄清一下:我只需要实现线程。 该数据库已经实施。

如何检测我们是否在UI线程上?

为了参数起见,将UI线程视为已调用Application.Run()一个线程,或者调用其中一个重载并且有一个活动的消息循环运行。 有没有办法检测我们当前是否正在这样的线程上执行? 我想要这个的原因是因为我有一个具有长期运行的私有函数的类。 该类本身已经是multithreading的,并且该类的使用使得它可以从UI或后台线程进行处理。 这个function也属于这个网络。 但我不希望它阻止UI线程。 所以我想检测我是否在UI线程上运行,如果是这样,将函数调用转换为后台线程(可能是ThreadPool ,但这对于此讨论来说不是问题)。 这完全是表现良好的,但后台线程可能依赖于函数的输出,因此阻塞它们更好,而UI线程以更“一劳永逸”的方式访问它。