Tag: multithreading

Thread.CurrentThread.CurrentCulture不在线程池内的线程中工作

我有一个方法将在一个线程内调用,这些线程由线程池管理。 该方法调用DLL的方法,遗憾的是,该方法需要特定的语言环境才能正确执行。 在通过threadpool运行此方法之前,我已经在应用程序的主线程中运行时进行了测试,同时我手动管理线程并且工作正常,但是当我将其放入线程池内工作时,语言环境不会应用,因此该方法行为不正确。 以下是应该受区域设置更改影响的方法部分(但行为不正常): CultureInfo before = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = new CultureInfo(“fa-IR”); int result = tsms.SendSMS(smsTask.MobileNumber.MobileNumberInString, smsTask.Message); Thread.CurrentThread.CurrentUICulture = before; 这是线程池创建结构: foreach (SMSTask smsTask in tasksList) { if (this.threadsCount < this.threadPoolSize) { this.threadsCount++; ThreadPool.QueueUserWorkItem(new WaitCallback(SendMessage), (object)smsTask); } } 我也尝试将locale设置为如下所示的线程对象,但它没有解决问题:(第2行和第3行): threadObject = new Thread(new ThreadStart(TaskProcessingThreadFunction)); threadObject.CurrentCulture = new CultureInfo(“fa-IR”); threadObject.CurrentUICulture = new CultureInfo(“fa-IR”); threadObject.Start(); 请指导我在线程池中运行此方法时应该如何获得正确的结果。 更新后的版本: […]

使用ReaderWriterLock的真正缺点是什么?

我们有项目针对.NET 2.0 RTM(是的,它应该是.NET 2.0 RTM,我们有一些正统的客户端)。 而我只是想知道ReaderWriterLock的缺点是什么? 为什么每个人都说“不要使用它,尝试使用lock语句之类的东西”这么糟糕? 如果我们可以使用.NET 3.5,我肯定会使用ReaderWriterLockSlim ,但是对于ReaderWriterLock我对来自各地的所有这些警告感到有点害怕。 有人测量过表现还是其他什么? 如果存在一些性能问题,我们可以在哪些有效负载下遇到它们? 我们在ReaderWriterLock主要目的方面有一个经典的情况,即多次读取和很少写入。 使用lock语句会阻止所有读者。 也许对我们来说这不是一个可怕的问题,但如果我能使用ReaderWriterLock我会更满意。 IMO介绍几台显示器确实是一个非常糟糕的主意。

c#事件执行是线程安全的吗?

我阅读了很多事件和线程讨论,但是如果我从事件中取消并稍后尝试调用它,那么所有这些都会集中在“会发生什么”。 我的问题是不同的……如果我在线程A中有一个进程以毫秒1触发事件“我完成”,并且在线程B中有一个进程以毫秒2触发事件“我完成”将会发生什么。 这两个进程都被用于监听和处理事件的相同方法。 因此,C#必须执行处理事件2次的方法:1次用于在线程A中触发的事件,1次用于从线程B触发的事件。 会发生什么?? 当“来自线程A的第一个事件”开始执行处理事件的方法时,C#是否锁定方法,并在完成执行时解锁方法,从而允许其他等待“事件”执行方法内容? 或者从线程A触发的事件将开始执行处理事件的方法,1毫秒后,从线程B触发的事件也将在相同的方法上开始执行,而不会注意到当前该方法正由其他方执行“处理”??? 我问这个,因为我想在捕获事件的方法中写一些文件,但如果方法可以同时执行(取决于事件被触发的时间),我想我不能在这里做,因为关于该文件将是同时写入同一文件的2个进程之间的混合(不是文件的有效信息)。 我的代码看起来像这样(有点长,对不起)。 请注意这不会编译,只是一个示例,以显示我在做什么: public partial class MainForm : Form { FTPClientManager client = null; public MainForm() { InitializeComponent(); } private void btnConnect_Click(object sender, EventArgs e) { Connect(this.tbFTPServer.Text.Trim()); this.lstLog.Items.Add(“Connected”); //This lstLog is a list box that will have a list of downloaded files from all threads. } void Connect(string […]

C#在添加的线程中触发事件

考虑两个class级; Producer和Consumer (与经典模式相同,每个都有自己的线程)。 Producer是否可以拥有一个Consumer可以注册的事件,当生产者触发事件时,消费者的事件处理程序是在自己的线程中运行的? 以下是我的假设: Consumer不知道Producer的事件是否在他自己的线程或其他线程中被触发。 Producer和Consumer都不是Control后代,因此它们没有inheritanceBeginInvoke方法。 PS。 我不打算实现Producer – Consumer模式。 这是两个简单的类,我正在尝试重构生成器,因此它包含线程。 [UPDATE] 为了进一步扩展我的问题,我试图以最简单的方式包装硬件驱动程序。 例如,我的包装器将有一个StateChanged事件,主应用程序将注册该事件,以便在硬件断开连接时通知它。 由于实际的驱动程序除了轮询以外没有任何其他方法来检查它的存在,我将需要启动一个线程来定期检查它。 一旦它不再可用,我将触发需要在添加的同一线程中执行的事件。 我知道这是一个经典的Producer-Consumer模式,但由于我正在尝试简化使用我的驱动程序包装器,我不希望用户代码实现使用者。 [UPDATE] 由于一些评论表明没有解决这个问题的方法,我想补充一些可能会改变他们想法的路线。 考虑到BeginInvoke可以做我想要的,所以它不应该是不可能的(至少在理论上)。 实现我自己的BeginInvoke并在Producer调用它是一种查看它的方法。 只是我不知道BeginInvoke是如何做到的!

快速有效地下载多个文件(异步)

我有这么多文件,我必须下载。 所以我尝试使用新的异步function,如下所示。 var streamTasks = urls.Select(async url => (await WebRequest.CreateHttp(url).GetResponseAsync()).GetResponseStream()).ToList(); var streams = await Task.WhenAll(streamTasks); foreach (var stream in streams) { using (var fileStream = new FileStream(“blabla”, FileMode.Create)) { await stream.CopyToAsync(fileStream); } } 我担心这段代码会导致大量内存使用,因为如果有1000个文件包含2MB文件,那么这段代码会将1000 * 2MB流加载到内存中? 我可能会遗漏一些东西,或者我完全正确。 如果我没有错过任何东西,那么最好等待每个请求和消费流是最好的方法吗?

为什么不允许锁定(),但允许使用Monitor.Enter()?

对于以下代码,我得到编译时错误,* ‘int’不是lock语句所要求的引用类型 int i = 0; lock(i); 但没有错误: int i = 0; Monitor.Enter(i); 据我所知,由于拳击造成的并发症,不应使用值类型进行锁定。 但是,为什么它与Monitor一起使用。

在C#中运行多个任务

我正在开发一个实时软件,我有一些非实时function。 眼镜: 需要实时做方法1; 需要每60分钟做一次方法2。 我应该使用multithreading吗? 任务? 现在我正在使用计时器,但不认为它是一个很好的用途。

Interlocked是否提供所有线程的可见性?

假设我有一个变量“counter”,并且有几个线程通过使用Interlocked访问和设置“counter”的值,即: int value = Interlocked.Increment(ref counter); 和 int value = Interlocked.Decrement(ref counter); 我可以假设,Interlocked所做的更改将在所有线程中可见吗? 如果没有,我该怎么做才能使所有线程同步变量? 编辑:有人建议我使用volatile。 但是当我将“计数器”设置为volatile时,会有编译器警告“对volatile字段的引用不会被视为volatile”。 当我阅读在线帮助时,它说:“通常不应使用ref或out参数传递易失性字段”。

应用程序关闭时的任务处理

我有一个.Net(v4.0)Windows服务应用程序,它在开始时旋转一个tpl任务,执行某些长时间运行的活动,并且基本上在应用程序的生命周期内保持活动状态,因此使用TaskCreationOptions创建。 LongRunning参数值。 每当服务停止并且.OnStop()方法被调用时,我.Cancel()我在创建它时移交给工作任务的CancellationToken(Source)我想要它.OnlyOnCanceled(…)继续任务到跑。 问题是,服务/流程关闭而没有继续任务“完全”运行 – 有时它会相当快地退出,有时它会完全运行,有时则不会。 这对我来说是有意义的,因为该特定任务可能位于另一个线程而不是主线程上,因此无法“阻止”/阻止主要任务结束。 因为我在那个Windows服务应用程序中没有SynchronizationContext,所以我无法告诉延续任务在主线程上运行/所以我想知道:我该怎么做? 更确切地说,运行tpl任务处理应用程序关闭的最佳实践是什么?

从后台Worker更新ObservableCollection

我有一个DatGrid,它绑定到var Result_Full = new ObservableCollection() 。 这是一个包含多个字符串和双变量的简单类。 没什么难的。 我所做的是,我读了一个Excel文件(使用Telerik RadSpreadProcessing),它将行解析到我的类中。 我在一个线程上执行此操作,以便不阻止UI。 我遇到了一些问题: 1)我不能在读取excel文件的长进程中使用ref关键字(因为Result_Full是绑定到DataGrid的公共属性),但是我必须创建临时ObservableCollection() ,其中放置值。 完成该过程后,我运行以下脚本来复制值: foreach (var item in tmpFull) { InvokeOnUIThread(() => { Result_Full.Add(item); }); } 我想做的是,能够实时查看(如果可能)如何将项目添加到我的DataGrid中的集合中。 当我使用.Net 4.5时,我尝试按照其他post的建议实现BindingOperations.EnableCollectionSynchronization ,但我无法弄清楚如何将我的UI模型集合Result_Full绑定到进程中临时使用的。 2)即使使用当前设置,当我(在我的UI下)移动到包含DataGrid的我的Tab(我的DataGrid在不同的TabPage上)时,我尝试使用上面提到的代码将新项添加到集合中,它返回错误说: 调用线程无法访问此对象,因为另一个线程拥有它。 ,这是相当奇怪的,因为InvokeOnUIThread只是Dispatcher.Invoke() ,它应该是线程安全的? 任何帮助将受到高度赞赏。 编辑:显示更多代码: 这是我从BackgroundWorker调用的过程: public void ProcessFile() { var tmpError = new ObservableCollection(); var tmpFull = new ObservableCollection(); var _reader = […]