Tag: 同步

即使在Monitor.Enter之后,Monitor.TryEnter也始终返回true

我想我错过了关于Monitor.Enter和Monitor.TryEnter正确行为的一些信息。 这是我编写的一段代码,用于将问题与其余代码分开: object lockObj = new object(); bool result = Monitor.TryEnter(lockObj); Console.Write(result); 结果总是true 。 这里没有惊喜。 object lockObj = new object(); Monitor.Enter(lockObj); bool result = Monitor.TryEnter(lockObj); Console.Write(result); 但这一次也是true 。 那么在Monitor.Enter之后lockObj锁定了lockObj ? 请给我一些新的看法。

是否有更好的方法来限制高吞吐量的工作?

我创建了一个简单的类,显示我想要做的没有任何噪音。 随意抨击我的代码。 这就是我在这里发布的原因。 public class Throttled : IDisposable { private readonly Action work; private readonly Func stop; private readonly ManualResetEvent continueProcessing; private readonly Timer throttleTimer; private readonly int throttlePeriod; private readonly int throttleLimit; private int totalProcessed; public Throttled(Action work, Func stop, int throttlePeriod, int throttleLimit) { this.work = work; this.stop = stop; this.throttlePeriod = throttlePeriod; […]

在.net中的lock语句中调用Thread.Sleep()

我想知道在一个已经获得监视器的线程上调用Threa.Sleep是否会在进入睡眠状态之前释放锁定: object o = new object(); Montior.Enter(o); Thread.Sleep(1000); Monitor.Exit(o); 线程被挂起 – 其他线程可以获得吗?

等待任何线程完成,而不是全部

我正在启动多个线程,想知道什么时候结束。 我知道以下代码: foreach (Thread t in threads) t.Join(); 但它只会等待所有线程在一起。 那太晚了。 我需要知道一个线程何时完成,即使其他线程仍在运行。 我正在为线程寻找等同于WaitAny东西。 但我无法将代码添加到我正在监视的所有线程中,因此使用信号或其他同步对象不是一种选择。 一些澄清:我正在开发一个记录/跟踪工具,它应该记录应用程序的活动。 我可以在线程启动时插入日志语句,但是我不能在线程的每个可能的方式上插入日志语句(多个出口点,exception等)。 所以我想注册新线程,然后在完成写入日志条目时收到通知。 我可以异步Join每个线程,但这意味着每个受监控线程的第二个线程可能看起来有点开销。 线程通过各种方式使用,无论是BackgroundWorker , Task还是池线程。 从本质上讲,它是一个线程,我想知道它什么时候完成。 确切的线程机制由应用程序定义,而不是日志记录解决方案。

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

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

这个锁用法线程安全吗?

我知道使用lock(this)或任何共享对象是错误的。 我想知道这种用法是否合适? public class A { private readonly object locker = new object(); private List myList; public A() { myList = new List() } private void MethodeA() { lock(locker) { myList.Add(10); } } public void MethodeB() { CallToMethodInOtherClass(myList); } } public class OtherClass { private readonly object locker = new object(); public CallToMethodInOtherClass(List list) { […]

volatile作为同步机制

假设我有一个类Foo,它有一个名为Count的静态成员变量(类型为整数)。 此变量用于multithreading应用程序,我在对此变量进行任何读/写操作之前使用锁同步机制。 正如我正在阅读本文的易变性我得到的印象是我可以删除围绕此变量的所有锁定,并在声明此变量时使用volatile关键字。 这应该照顾所有与synchnronization相关的东西。 它是否正确? 这种方法有哪些优缺点?

将文本框中的文本复制到datagridview的更好方法

美好的一天! 我有这个问题,文本框中的每个文本更改,datagriview中的选定项应该复制其值。 我有这个代码,但是当我在文本框中输入(非常快)时它会滞后。 有没有更好的方法来做这个没有滞后? 请帮忙… 这是我到目前为止所拥有的: private void txtText_TextChanged(object sender, EventArgs e) { DataGridView1[2, pos].Value = txtText.Text; }

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

我使用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 […]

如何处理在一个平台上同步但在另一个平台上异步的代码

在编写基于Xamarin的跨平台C#应用程序时,我经常遇到的情况是在一个平台上同步但在另一个平台上异步的代码。 例如,文件访问在iOS,Android和Mac上是同步的,但在Windows上是异步的。 这导致了一些棘手的问题。 首先,在纯编码级别上,编译器希望方法是异步还是不同步。 但它比这更糟糕。 例如,如果iOS UI线程发现它需要加载一个小文件,并且在UI线程上同步这样做,这可能不会对用户造成任何明显的打嗝。 是的,我意识到,作为一般规则,人们希望预先加载这些资源。 但如果没有发生,并且文件很小,那就不会导致问题。 但是,如果从iOS UI代码调用C#异步方法并等待结果,应用程序将挂起。 结果是我们有两个方法,Foo()和FooAsync(),我们调用哪个方法取决于平台。 但我们不能只让整个事情变得异步。 鉴于此,如何组织一个代码尽可能地坚持DRY,同时在一个平台上保持同步并在另一个平台上保持同步? ** 编辑 – 响应一个例子的请求:这里有一些虚拟代码来说明问题。 如果有人打电话 await StringLoaders.ReadAllText(somePath) 从iOS UI线程,结果是挂起。 是的,这个特定的例子有解决方法。 但一般问题是反复出现的问题。 如果应用程序有很多层,这是特别糟糕的,因为这样做 – 可能需要在整个代码中携带同步/异步区别,从而产生大量方法的两个版本。 public class AsyncStringLoader { public async Task ReadAllTextAsync(string path) { return await Task.Run(() => “Hello”); } } public class StringLoader { public string ReadAllText(string path) { return […]