我有一个场景,当我用ThreadPool启动3..10个线程.每个线程都完成它的工作并返回ThreadPool.所有后台线程完成后,主线程中可以通知哪些选项?
目前我正在使用一种自行开发的方法,为每个创建的线程递增一个变量,并在后台线程即将完成时递减它.这很好用,但如果有更好的选择,我很好奇.
下面两段代码有什么区别?使用第二个问题会有任何问题吗?
场景1:
private void Log(Exception e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Log), e);
}
private void Log(object obj)
{
Exception e = (Exception)obj;
Logger.Log(e);
}
Run Code Online (Sandbox Code Playgroud)
情景2
private void Log(Exception e)
{
ThreadPool.QueueUserWorkItem(
(obj) =>
{
Logger.Log(e);
});
}
Run Code Online (Sandbox Code Playgroud)
在方案2中,我没有将异常作为参数传递给ThreadPool.如何发生异常对象的线程编组?会有问题吗?这样做有什么限制?最大的优点是您可以非常轻松地传递任意数量的参数.
我在报告模式下有一个带有ListView的Windows窗体.对于视图中的每个项目,我需要执行一个长时间运行的操作,其结果是一个数字.
我在本机win32中执行此操作的方法是为每个项创建一个工作线程(天真地;当然我不会创建无限数量的线程),然后在线程句柄数组上创建MsgWaitForMultipleObjects().当每个计算完成时,线程信号和主UI线程唤醒并更新.同时,我们抽取消息,以便UI线程保持响应.
任何人都可以提供一个如何在C#中工作的例子吗?我看过Monitor对象,它似乎不是我想要的 - 或者是否在阻塞时抽取消息?
谢谢.
编辑:似乎WaitHandler.WaitAny()可能实际上是在发送消息.请参阅cbrumme关于 CLR中消息抽取的论文.
我有一个问题,我真的不认为有解决方案,但无论如何我会在这里尝试.我的应用程序使用线程池,并且此池中的某些线程具有可继承的线程局部变量.我已经扩展了ThreadPoolExecutor类,以便在线程完成执行时基本清除线程局部变量(在afterExecute回调方法中).
我知道当你有一个InheritableThreadLocal变量时,在初始化线程时调用childValue()方法以从父线程获取ThreadLocal变量的值.但是,在我的情况下,下次使用该线程时(在使用一次之后),InheritableThreadLocal变量的值为null(因为它之前已在afterExecute中清除).有没有办法在beforeExecute中访问父线程的线程局部变量,这样我就可以基本上模拟在创建线程时InheritableThreadLocal中的childValue方法.
我想在TLS中存储日志记录上下文信息,以便我可以在入口点设置一个值,并在所有结果栈中提供该值.这项工作很好,但我也使用TPL和ThreadPool.然后问题就变成了如何将TLS数据迁移到其他线程.我自己可以做到这一切,但后来我失去了像Parallel.For这样的好方法.
使用TPL时是否有某种方法可以复制TLS?当它获得await功能时,这也将适用于C#.
谢谢,埃里克
.net asynchronous threadpool task-parallel-library thread-local-storage
我正在研究由Win32异常引起的应用程序中的一些崩溃,并且我已经缩小它必须在线程池中发生,它正在EventLog.EntryWrittenEventHandler处理我的应用程序中的事件处理程序.我这样设置:
// Create the event log monitor
eventLog.Log = "Application";
eventLog.EnableRaisingEvents = true;
eventLog.EntryWritten += new EntryWrittenEventHandler(EventLogMonitor);
Run Code Online (Sandbox Code Playgroud)
EventLogMonitor是我的事件的处理程序.我想知道是否有任何想法,我在哪里可以找出导致此异常的原因.似乎要监听ThreadPoolWaitOrTimerCallback正在建立的事件,其上没有我的任何代码,如果发生异常,我就无法看到如何处理这个问题.任何帮助真的很感激!!
这是WinDBG中!clrstack的输出:
0:008> !clrstack
OS Thread Id: 0x106c (8)
ESP EIP
049df1c8 7756f871 [HelperMethodFrame: 049df1c8]
049df26c 73ce6fa0 System.Diagnostics.EventLog.get_OldestEntryNumber()
049df27c 73bf24ed System.Diagnostics.EventLog.CompletionCallback(System.Object)
049df2c4 73bf0fe4 System.Diagnostics.EventLog.StaticCompletionCallback(System.Object, Boolean)
049df2f4 744fc3b8 System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(System.Object, Boolean)
049df300 744fc373 System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(System.Object)
049df304 7400027f System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
049df31c 744fc477 System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)
049df4ac 74991b5c [GCFrame: 049df4ac]
Run Code Online (Sandbox Code Playgroud)
如果它有帮助,我的应用程序只是检查写入事件日志的每个条目的事件ID,如果它匹配某个ID的一个,那么我记录它.崩溃很少发生安静,异常是System.ComponentModel.Win32异常,消息"访问被拒绝".听起来这可能是一个权限问题,但为什么它会在一段时间内正常工作然后突然崩溃.
我已经在java中学习了很多关于线程的教程,但我找不到答案.
我的问题是:如何同时运行两个独立的线程?
我的情况是:我有两个任务;
由于这两个任务是独立的,我想同时执行它们.
我尝试使用具有两个线程的线程池,但问题是数据库任务很快完成,但发送推送通知需要一些时间.
因此,当一个任务完成而另一个任务仍处于未决状态时,它会抛出异常.
我的代码也没有问题,因为它运行正常而不使用线程.
提前致谢
我们正在开发一个应用程序,通过接收来自3个不同来源的消息,可以影响一组对象.每条消息(来自任何来源)都有一个对象作为其目标.每个消息接收器将在其自己的线程上运行.
我们希望消息的处理(在接收之后)尽可能高速,因此针对目标对象的消息处理将使用来自线程池的另一个线程来完成.消息的处理将比从发送者读取/接收消息花费更长的时间.
我认为如果池中的每个线程仅专用于特定的一组对象,它会更快,例如:
Thread1 -> objects named A-L
Thread2 -> objects named M-Z
Run Code Online (Sandbox Code Playgroud)
每组对象(或线程)都有一个专用的消息队列待处理.
我的假设是,如果所需的唯一线程同步是在每个接收线程和一个处理线程之间,在需要将消息放入阻塞队列的持续时间内,它将比随机分配工作线程以处理更快消息(在这种情况下,可能有2个不同的线程与同一对象的消息).
我的问题实际上是两个部分:
人们是否同意将工作线程专用于特定对象集合是更好/更快的方法?
假设这是一种更好的方法,现有的Java ThreadPool类是否有办法支持这种方法?或者它是否要求我们编写自己的ThreadPool实现?
感谢您提供的任何建议.
这可能是更一般的问题,关于如何决定线程池大小,但让我们ThreadPoolTaskExecutor在这种情况下使用Spring .我对池核心和最大大小以及队列容量进行了以下配置.我已经阅读有关所有这些配置的意思是-有一个很好的答案在这里.
@SpringBootApplication
@EnableAsync
public class MySpringBootApp {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MySpringBootApp.class, args);
}
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
return executor;
}
}
Run Code Online (Sandbox Code Playgroud)
以上数字对我来说是随机的,我想了解如何根据我的环境正确设置它们.我将概述以下约束:
理想情况下,我想了解我需要考虑的其他约束,并基于它们对我的池和队列大小的合理配置.