Tag: multithreading

C#线程/锁定混乱

我有以下代码: var items = new List {“1”, “2”, “3”}; // 200 items foreach(var item in items) { ThreadPool.QueueUserWorkItem((DoWork), item); } private void DoWork(object obj) { lock(this) { using(var sw = File.AppendText(@”C:\somepath.txt”) { sw.WriteLine(obj); } } } 由于线程,出于某种原因,我得到了写入文件的200个项目的随机数。 60或127或有时只有3.如果我删除ThreadPool并只在原始foreach循环内写入,则所有200个项目都会成功写入。 不知道为什么会这样? 谢谢你的帮助。

允许对局部变量进行C#编译器优化并从内存中重新获取值

编辑 :我在问两个线程在没有正确同步的情况下同时访问相同数据会发生什么(在此编辑之前,该点未明确表达)。 我有一个关于C#编译器和JIT编译器执行的优化的问题。 请考虑以下简化示例: class Example { private Action _action; private void InvokeAction() { var local = this._action; if (local != null) { local(); } } } 请在示例中忽略读取_action可能会产生缓存和过期值,因为没有volatile说明符,也没有任何其他同步。 那不是重点:) 是否允许编译器(或实际上是运行时的抖动)优化对局部变量的赋值,而是从内存中读取_action两次: class Example { private Action _action; private void InvokeAction() { if (this._action != null) { this._action(); // might be set to null by an other […]

在我的下载程序中添加暂停和继续function

我正在用C#创建一个下载程序。 我正在使用WebClient类。 要在按钮上暂停下载,我可以考虑使用Thread。 因此,当我创建线程并将其与我的文件下载附加如下 WebClient web = new WebLCient(); Thread dwnd_thread = new Thread(Program.web.DownloadFileAsync(new Uri(Program.src), Program.dest)); 它给了我以下错误:“’System.Threading.Thread.Thread(System.Threading.ThreadStart)’的最佳重载方法匹配’有一些无效的参数”和“Argument’1’:无法从’void’转换为’ System.Threading.ThreadStart’”。 然后我想如果我暂停我的系统主线程然后它可以阻止我在下面的代码行使用的整个过程 System.Threading.Thread.Sleep(100); 但它什么都不做。 有人可以告诉我什么是更好的暂停/下载方法以及如何使用线程暂停我的下载过程。

在迭代时修改另一个线程的列表(C#)

我正在使用foreach循环遍历元素列表,如下所示: foreach (Type name in aList) { name.doSomething(); } 但是,在另一个线程中我称之为 aList.Remove(Element); 在运行时,这会导致InvalidOperationException:Collection已被修改; 枚举操作可能无法执行。 处理这个问题的最佳方法是什么(即使以性能为代价,我会更加简单)? 谢谢!

等待两个线程完成

如果你有一个主线程启动另外两个线程。 什么是使主线程等待其他两个线程最干净的方法? 我可以使用bgndworker和sleep spinner来检查bgnd worker的IsBusy,但我认为有更好的方法。 编辑更多要求: 主线程还有其他一些工作要做(例如GUI)。 两个衍生线程应该能够报告exception并返回结果值

锁定和管理锁定exception的解决方案有什么问题?

我的目标是在我的应用程序中使用线程安全function和exception处理的约定。 我对线程管理/multithreading的概念比较陌生。 我使用的是.NET 3.5 在阅读本文http://blogs.msdn.com/b/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix后,我编写了以下帮助方法来包装所有锁定的操作。 aspx ,它是针对这个问题而链接的, Monitor vs lock 。 我的想法是,如果我在我的应用程序中一致地使用此约定,那么编写线程安全代码并在线程安全代码中处理错误将更容易,而不会破坏状态。 public static class Locking { private static readonly Dictionary CorruptionStateDictionary = new Dictionary(); private static readonly object CorruptionLock = new object(); public static bool TryLockedAction(object lockObject, Action action, out Exception exception) { if (IsCorrupt(lockObject)) { exception = new LockingException(“Cannot execute locked action on […]

WaitHandle.WaitAny和Semaphore类

编辑:我甚至想问这个问题暂时疯狂,但当时有意义(见下面的编辑2)。 对于.NET 3.5项目,我有两种类型的资源( R1和R2 ),我需要检查它的可用性。 每种资源类型可以随时(例如)有10个实例。 当其中一种资源可用时,我的工作线程需要唤醒(存在可变数量的线程)。 在早期的实现中,只有一种资源类型,我使用信号量来检查可用性。 现在我需要等待两个单独的信号量( S1和S2 )来跟踪资源的可用性。 WaitHandle[] waitHandles = new WaitHandle[] { s1, s2 }; int signalledHandle = WaitHandle.WaitAny(waitHandles); switch (signalledHandle) { case 0: // Do stuff s1.Release(); case 1: // Do stuff s2.Release(); } 然而,这有一个问题。 从WaitAny上的MSDN文档: 如果在调用期间发出多个对象的信号,则返回值是信号对象的数组索引,其中所有信号对象的索引值最小。 这表明在调用WaitAny之后我可能会将我的信号量计数减少1。 因为signalledHandle将指示s1已发出信号,我将开始使用资源R1 ,并在完成后释放它。 但是,由于我不知道S2是否已发出信号,因此此资源的可用性计数现在可能已关闭。 如果发生这种情况10次,我的信号量将永久“空”,资源R2将不再使用。 处理这个问题的最佳方法是什么? 我是否应该从使用两个信号量切换到简单计数器,并在任何一个计数器更改时发出AutoResetEvent信号? 我错过了一些更优雅的方法吗? 编辑1: 根据Ravadre的说法,在WaitAny之后,只有一个信号量会被改变。 略微修改他的例子似乎证实了这一点,但有没有人可以指出我指出这个的一些官方文档? 编辑2: […]

C# – 参数在静态方法中是否安全?

这个方法是线程安全的吗? 好像它不是…… public static void Foo(string _str, Guid _id) { _str = _str + _id.ToString(); /* Do Stuff */ return }

.NET线程 – 分配需要锁定

我有一些multithreading代码,我想增加一点的性能,所以我想知道我是否可以摆脱锁。 我有一个现场成员: private IList status; 它在这样的线程中更新: status = GetUpdatedStatus(); 它在另一个线程中使用,如下所示: var currentStatus = status; 所以问题是,如果没有锁定两个赋值语句,上面会产生任何问题吗? 我想我能看到的唯一情况是currentStatus为null,但是我再次希望赋值有点线程安全(或者它已经更改了引用)

从另一个Thread更新MainWindow中的进度条

我知道这个问题已被问过几次,我花了一整天时间试图理解其他答案,但由于我对C#和WPF很新,所以到目前为止没有任何帮助。 我将尝试尽可能多地解释我的确切问题,这将直接帮助我。 在我的MainWindow.xaml中,我有一个进度条和一些按钮启动一个新线程和一个长计算: 现在在我的MainWindow.xaml.cs中: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(new ParameterizedThreadStart(MyLongCalculation)); ParameterClass myParameters = new ParameterClass(); thread.Start(myParameters); } public void MyLongCalculations(object myvalues) { ParameterClass values = (ParameterClass)myvalues; //some calculations } } public class ParameterClass { //public variables… […]