Tag: multithreading

如何取消线程?

对于BackgroundWorker ,可以通过DoWork的e.Cancel属性报告取消 – 事件处理程序。 如何使用Thread对象实现相同的function?

C#:让任务同时运行

我试图不停地运行几个任务。 这是我的代码: int maxThread = 100; Task[] tasks = new Task[maxThreads]; while(true) { for(int i = 0;i<maxThreads;i++) { tasks[i] = new Task.Factory.StartNew(someTask); } Task.WaitAll(tasks); } 因此,此函数等待所有任务完成并运行下一批任务。 但是我希望一旦完成任务就开始执行任务,而不必等待其他任务。 谢谢!

.NET有没有办法获得父线程ID?

假设主线程正在生成一个新线程t1,我在t1上运行的代码如何找到主线程的线程id(使用c#)? 编辑: 我不控制新线程的创建。 所以我不能将任何参数传递给线程。 谢谢。

定期以指定的时间间隔运行异步方法

我需要从C#Web应用程序向服务发布一些数据。 用户使用应用程序时收集数据本身(一种使用统计信息)。 我不希望在每个用户的请求期间向服务发送数据,我宁愿在应用程序中收集数据,然后在一个单独的线程中发送单个请求中的所有数据,这不会满足用户的请求(我的意思是用户不必等待服务处理请求)。 为此,我需要一种JS的setInterval模拟 – 每隔X秒启动一次函数,将所有收集的数据刷新到服务中。 我发现Timer类提供了一些类似的( Elapsed事件)。 但是,这允许只运行一次方法,但这不是一个大问题。 它的主要困难是需要签名 void MethodName(object e, ElapsedEventArgs args) 虽然我想启动异步方法,它将调用web服务(输入参数并不重要): async Task MethodName(object e, ElapsedEventArgs args) 任何人都可以建议如何解决所描述的任务? 任何提示赞赏。

我应该使用等待异步Action方法吗?

我需要在我的Controller中实现一个异步Action,用于长时间运行的外部API调用。 看一些教程,我已经实现了我的方法: [AsyncTimeout(200)] public async Task DoAsync() { // Execute long running call. return View(); } 我的问题是,这足以使真正的非块异步吗? 我是否还需要应用await运算符,如果是,我该怎么做?

如何在c#中执行线程安全的函数memoization?

在堆栈溢出这里我发现了记忆单参数函数的代码: static Func Memoize(this Func f) { var d = new Dictionary(); return a=> { R r; if (!d.TryGetValue(a, out r)) { r = f(a); d.Add(a, r); } return r; }; } 虽然这段代码对我来说很有用,但是当同时从多个线程调用memoized函数时,它会失败: Add方法被相同的参数调用两次并抛出exception。 如何使memoization线程安全?

管道,多路复用和无界缓冲

(注意:我使用的是.Net 4, 而不是 .Net 4.5,所以我不能使用TPL的DataflowBlock类。) TL; DR版本 最后,我只是想找到一种方法来处理使用多个线程的顺序工作项,以便在最终输出中保留它们的顺序,而不需要无限制的输出缓冲区。 动机 我现有的代码提供了一个multithreading机制来处理多个数据块,其中一个I / O绑定线程(“供应商”)负责排队数据块以进行处理。 这些数据块包括工作项。 一个或多个线程(“处理器”)负责一次使一个工作项出列,然后处理这些工作项,然后在将其下一个工作项出列之前将处理后的数据写入输出队列。 最终的I / O绑定线程(“使用者”)负责从输出队列中出列已完成的工作项并将它们写入最终目标。 这些工作项目(并且必须)按照它们入队的顺序编写。 我使用并发优先级队列实现了这一点,其中每个项目的优先级由其源索引定义。 我正在使用这种方案在大数据流上进行一些自定义压缩,其中压缩本身相对较慢但是未压缩数据的读取和压缩数据的写入相对较快(尽管受I / O限制)。 我以64K的相当大的块处理数据,因此管道的开销相对较小。 我目前的解决方案运行良好,但它涉及6年前使用许多同步事件编写的大量自定义代码,并且设计看起来有些笨拙; 因此,我已经开始学术练习,看看它是否可以使用更现代的.Net库进行重写。 新设计 我的新设计使用了BlockingCollection类,并且基于这篇Microsoft文章 。 特别是,请查看标题为使用多个生产者进行负载平衡的部分。 我尝试过使用这种方法,因此我有几个处理任务,每个任务都从共享输入BlockingCollection获取工作项,并将完成的项写入自己的BlockingCollection输出队列。 因为每个处理任务都有自己的输出队列,所以我试图使用BlockingCollection.TakeFromAny()来取消第一个可用的已完成工作项。 多路复用器问题 到目前为止一切顺利,但现在问题来了。 微软文章指出: 差距是个问题。 管道的下一个阶段,即显示图像阶段,需要按顺序显示图像,并且序列中没有间隙。 这是多路复用器的用武之地。使用TakeFromAny方法,多路复用器等待来自两个filter阶段生产者队列的输入。 当图像到达时,多路复用器查看图像的序列号是否是预期序列中的下一个。 如果是,则多路复用器将其传递到显示图像阶段。 如果图像不是序列中的下一个图像,则多路复用器将值保存在内部前瞻缓冲区中,并对没有前瞻值的输入队列重复获取操作。 此算法允许多路复用器以确保顺序排序而不对值进行排序的方式将来自传入生成器队列的输入组合在一起。 好的,所发生的是处理任务可以几乎任何顺序生成完成的项目。 多路复用器负责以正确的顺序输出这些项目。 然而… 想象一下,我们有1000件待处理的物品。 进一步想象一下,由于一些奇怪的原因,第一个项目需要更长的时间来处理所有其他项目的组合。 使用我当前的方案,多路复用器将继续读取和缓冲来自所有处理输出队列的项目,直到它找到它应该输出的下一个项目。 由于它等待的项目(根据我的“想象如果”)仅在处理完所有其他工作项后才出现,我将有效地缓冲整个输入中的所有工作项! 数据量太大,无法实现。 当输出队列达到某个最大大小时(即它是一个有界的输出队列),我需要能够停止处理任务输出已完成的工作项,除非工作项恰好是多路复用器正在等待的工作项。 这就是我有点陷入困境的地方。 我可以想出很多方法来实际实现它,但它们似乎都过于复杂,以至于它们并不比我想要替换的代码更好! 我的问题是什么? 我的问题是:我是否以正确的方式解决这个问题? 我本以为这是一个众所周知的问题,但是我的研究只发现了一些文章,这些文章似乎忽略了如果工作项与其他所有工作项相比需要很长时间而发生的无限缓冲问题。 […]

何时使用volatile来抵消C#中的编译器优化

我花了很多周时间在C#4.0中进行multithreading编码。 但是,有一个问题对我来说仍然没有答案。 我知道volatile关键字阻止编译器将变量存储在寄存器中,从而避免无意中读取过时值。 写入在.Net中始终是易变的,因此任何说明它也避免了stales写入的文档都是多余的。 我也知道编译器优化有些“不可预测”。 以下代码将说明由于编译器优化而导致的停顿(在VS之外运行发布编译时): class Test { public struct Data { public int _loop; } public static Data data; public static void Main() { data._loop = 1; Test test1 = new Test(); new Thread(() => { data._loop = 0; } ).Start(); do { if (data._loop != 1) { break; } //Thread.Yield(); } while […]

IIS中的请求是否会在单个线程上运行?

我们有一个在IIS中运行的系统。 系统应始终使用相同的“文化”运行,但我们不能依赖正确设置的服务器设置。 一种方法是在每次进行ToString时指定文化。 但是,我们想知道,是否有可能在方法开始时在一个线程上设置文化并依赖该方法中的所有代码在同一个线程上运行?

使用MVVM中的后台worker更新ObservableCollection

好的,我最近实现了一个后台工作程序来执行数据的保存和加载。 但是,让它在save命令上工作已经certificate是困难的。 基本上,我的save命令生成一个事件,该事件通知集合视图模型,已添加Item,并且该项应添加到其自己的ObservableCollection中。 此时,我得到通常的exception,说我不能在不同的线程上更新ICollection。 我已经尝试创建一个调用Dispatcher.Invoke的新列表类型,但是这仍然会生成相同的exception。 我想知道是否有其他人对如何最好地解决这个问题有任何建议? 所以目前我有一个inheritance自ObservableCollection的类: public class ThreadSafeObservableCollection : ObservableCollection { public ThreadSafeObservableCollection(List collection) : base(collection) { dispatcher = Dispatcher.CurrentDispatcher; rwLock = new ReaderWriterLock(); } protected override void InsertItem(int index, T item) { if (dispatcher.CheckAccess()) { if (index > this.Count) return; LockCookie c = rwLock.UpgradeToWriterLock(-1); base.InsertItem(index, item); rwLock.DowngradeFromWriterLock(ref c); } else { object[] […]