Tag: 线程安全

use invoke和synchronizationcontext.Post对象有什么区别?

当我收到与线程上下文相关的exception时,我使用委托函数并调用此委托函数。 来自其他线程的使用控制是必要的。 但我刚学会了我可以使用SynchronizationContext.Post()函数,我可以在这个方法中调用我的委托。 但我不确定哪一个更好? 或者这些方法有什么区别。 非常感谢。

Microsoft企业库缓存应用程序块不是线程安全的?

我创建了一个超级简单的控制台应用程序来测试企业库缓存应用程序块,行为令人困惑。 我希望我搞砸了一些容易在设置中修复的东西。 为了测试目的,我让每个项目在5秒后过期。 基本设置 – “每秒选择0到2之间的数字。如果缓存还没有,请将其放在那里 – 否则只需从缓存中获取它。在LOCK语句中执行此操作以确保线程安全。 App.config中: C#: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Practices.EnterpriseLibrary.Common; using Microsoft.Practices.EnterpriseLibrary.Caching; using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations; namespace ConsoleApplication1 { class Program { public static ICacheManager cache = CacheFactory.GetCacheManager(“Cache Manager”); static void Main(string[] args) { while (true) { System.Threading.Thread.Sleep(1000); // sleep for one second. var key = new […]

围绕多个语句的锁定语句是否确保所有更改对其他线程可见(假设它们进入相同的互斥锁)?

如果在一个锁定代码块中有多个共享变量赋值,它是否一定意味着所有这些更改对其他线程立即可见,一旦在同一对象上输入锁定语句就可能在其他处理器上运行 – 或者没有这样的保证? 很多例子都显示了一个常见变量的“set”或“get”,并详细介绍了内存障碍,但如果内部有更复杂的语句,会发生什么? 有可能甚至函数调用做其他事情? 像这样的东西: lock(sharedObject) { x = 10; y = 20; z = a + 10; } 如果此代码在另一个可能在另一个处理器上执行的线程上运行,它是否会对更改的“可见性”做出任何保证? lock (sharedObject) { if (y == 10) { // Do something. } } 如果答案是否定的 – 也许并解释这些变化何时可见?

在C#中确保静态方法的线程安全性

我有一些我目前在静态类/方法中的代码,但我想检查它是否是线程安全的。 从我读过的内容来看,我认为这应该没问题,但我脑海中的一些事情却说它可能不是。 我的网页的数据处理阶段使用外部Web服务来创建订单记录,这可能非常慢:可能是30-40秒,可能是5或10分钟(这不在我的手中)所以我要开火返回页面返回给用户,然后启动新线程,然后在处理完成后通过电子邮件发送给用户。 这是一个静态类/方法。 如果我的所有对象都是在特定方法中创建的(除了系统默认值,这是常见的)该方法应该是线程安全的,不应该。 所以,例如,如果我有 public static class ProcessOrder() { public static int GetOrderMaxSize() { return (….gets and parses ConfigurationManager.AppSettings[“MaxOrderSize”]…); } public static bool CreateOrder(Order order) { XmlDocument xmlDoc = GetOrderXML(order); bool check = false; using (CreateOrderXML.Create xmlCo = new CreateOrderXML.Create()) { xmlCo.Timeout = 60000; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); string xmlString = “”; […]

急切地处理ManualResetEvent

我有一个类允许其他线程等到它使用ManualResetEventSlim完成一个操作。 (操作通常很简短) 这个类没有明确的生命周期,因此没有一个地方可以轻松关闭事件。 相反,我希望在事件结束后立即关闭事件 – 一旦发出信号,并且在任何等待的线程唤醒之后。 出于性能原因,我宁愿不使用锁。 这段代码是否是线程安全的,可以更快吗? volatile bool isCompleted; volatile int waitingCount; ManualResetEventSlim waiter = new ManualResetEventSlim(); //This method is called on any thread other than the one that calls OnCompleted public void WaitForCompletion() { if (isCompleted) return; Interlocked.Increment(ref waitingCount); Thread.MemoryBarrier(); if (!isCompleted) waiter.Wait(); if (0 == Interlocked.Decrement(ref waitingCount)) { waiter.Dispose(); waiter = […]

这是ConcurrentDictionary和ConcurrentQueue线程安全的组合吗?

我在以下代码中使用.NET 4中的ConcurrentDictionary和ConcurrentQueue类。 这段代码是线程安全的吗? 如果没有,我怎样才能使它成为线程安全的? public class Page { public string Name {get; set; } } public class PageQueue { private ConcurrentDictionary<int, ConcurrentQueue> pages = new ConcurrentDictionary<int, ConcurrentQueue>(); public void Add(int id, Page page) { if (!this.pages.ContainsKey(id)) this.pages[id] = new ConcurrentQueue(); this.pages[id].Enqueue(page); } public Page GetAndRemove(int id) { Page lp = null; if(this.pages.ContainsKey(id)) this.pages[id].TryDequeue(out lp); return […]

Windows服务中的多个线程

我有一个Windows项目和一个表格,每5秒有一个计时器。 它从请求命名表时间和条件方式调用和处理方法。 但我有一些方法类型需要花费太多时间来响应并希望这些方法在单独的线程中。 这样我就可以在单独的线程和同步中运行这两种请求类型。 如何使用线程 – 多异步线程将它们分开?

串行任务执行器; 这个线程安全吗?

我使用ThreadPool作为执行手段,创建了一个允许异步顺序执行任务的类。 我的想法是,我将在后台运行串行任务的多个实例,但我不希望每个实例都有一个单独的专用线程。 我想检查的是这个类是否真的是线程安全的。 这是相当简短的,所以我想我会由专家在这里运行它,以防我遗漏了一些明显的东西。 我省略了一些针对不同Action类型的方便重载。 /// /// This class wraps ThreadPool.QueueUserWorkItem, but providing guaranteed ordering of queued tasks for this instance. /// Only one task in the queue will execute at a time, with the order of execution matching the order of addition. /// This is designed as a lighter-weight alternative to using a dedicated […]

使“修改时枚举”集合成为线程安全的

我想创建一个可以在枚举时修改的线程安全集合。 示例ActionSet类存储Action处理程序。 它有Add方法,它为列表添加一个新的处理程序,以及枚举和调用所有收集的操作处理程序的Invoke方法。 预期的工作方案包括非常频繁的枚举,在枚举时偶尔进行修改。 如果在枚举未结束时使用Add方法修改它们,则正常集合会抛出exception。 这个问题有一个简单但缓慢的解决方案:在枚举之前克隆集合: class ThreadSafeSlowActionSet { List _actions = new List(); public void Add(Action action) { lock(_actions) { _actions.Add(action); } } public void Invoke() { lock(_actions) { List actionsClone = _actions.ToList(); } foreach (var action in actionsClone ) { action(); } } } 这个解决方案的问题是枚举开销,我希望枚举非常快。 我创建了一个相当快速的“递归安全”集合,允许在枚举时添加新值。 如果在枚举main _actions集合时添加新值, _actions将值添加到临时_delta集合而不是主集合。 完成所有枚举后, _delta值将添加到_actions集合中。 如果在枚举main _actions集合时添加一些新值(创建_delta集合),然后再次重新输入Invoke方法,我们必须创建一个新的合并集合( […]

collections被修改; 枚举操作可能无法执行。 锁在哪里可用?

这是一个只有我正在编写和使用的小程序。 现在我要编写所有使用导致此问题的hashset的区域的代码 我不明白这是怎么可能的。 此项目仅在MainWindow中使用 hsProxyList是一个哈希集 HashSet hsProxyList = new HashSet(); 错误发生在下面的迭代中 lock (hsProxyList) { int irRandomProxyNumber = GenerateRandomValue.GenerateRandomValueMin(hsProxyList.Count, 0); int irLocalCounter = 0; foreach (var vrProxy in hsProxyList) { if (irLocalCounter == irRandomProxyNumber) { srSelectedProxy = vrProxy; break; } irLocalCounter++; } } } 我使用hsProxyList的其他地方 我在计算时没有锁定对象 – 我想这不会导致任何错误,但可能不正确 – 不重要 lblProxyCount.Content = “remaining proxy count: ” […]