小编ale*_*exg的帖子

为什么使用JpegBitmapDecoder的LongRunning任务(TPL)资源耗尽?

我们有一个托管的.Net/C#应用程序,可以创建TPL任务来对JPEG图像执行JPEG元数据编码.每个任务都使用TaskCreationOptions.LongRunning选项构建,例如,

Task task = new Task( () => TaskProc(), cancelToken, TaskCreationOptions.LongRunning );
Run Code Online (Sandbox Code Playgroud)

TaskProc()利用JpegBitmapDecoder和JpegBitmapEncoder类添加JPEG元数据并将新图像保存到磁盘.我们允许在任何时间最多激活2个此类任务,此过程应无限期地继续.

执行上述操作一段时间后,我们得到了足够的存储空间可用于在尝试创建JpegBitmapDecoder类的实例时处理此命令异常:

System.ComponentModel.Win32Exception(0x80004005的):没有足够的存储可在MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d)处理此命令
在MS.Win32.HwndWrapper..ctor(的Int32 classStyle,的Int32风格的Int32扩展风格,INT3 2×,的Int32 Y,的Int32宽度,高度的Int32,字符串名称,IntPtr的父,HwndWrapperHoo K []钩子)在System.Windows.Threading.Dispatcher..ctor()在System.Windows.Threading.Dispatcher.get_CurrentDispatcher()在System.Windows.Media.Imaging.BitmapDecoder..ctor(流bitmapStream,BitmapC reateOptions createOptions,BitmapCacheOption cacheOption,的Guid expectedClsId)在System.Windows.Media.Imaging.JpegBitmapDecoder..ctor(流bitmapStream,位mapCreateOptions createOptions,BitmapCacheOption cacheOption)

当我们使用JpegBitmapDecoder添加元数据时才会发生错误.换句话说,如果任务只是编码并将Bitmap图像保存到文件,则不会出现任何问题.使用Process Explorer,Process Monitor或其他诊断工具时,没有发现任何明显的事实.根本没有观察到线程,内存或手柄泄漏.发生此类错误时,不会启动任何新应用程序,例如记事本,文字等.一旦我们的应用程序终止,一切都会恢复正常.

LongRunning的任务创建选项在MSDN中定义为指定任务将是长时间运行的粗粒度操作.它向TaskScheduler提供了一个提示,即可以保证超额订阅.这意味着选择运行任务的线程可能不是来自ThreadPool,即,它将为任务的目的而创建.其他任务创建选项将导致为任务选择ThreadPool线程.

经过一段时间的分析和测试,我们将任务创建选项更改为除LongRunning之外的任何其他选项,例如PreferFairness.根本没有对代码进行任何其他更改.这"解决了"问题,即不再耗尽存储错误.

我们对LongRunning线程成为罪魁祸首的实际原因感到困惑.以下是我们对此的一些问题:

  1. 为什么选择执行任务的线程来自ThreadPool?如果线程终止,那么GC的资源是否应该随时间回收并返回操作系统,无论其来源如何?

  2. LongRunning任务和导致错误的JpegBitmapDecoder功能的组合有什么特别之处?

.net c# task-parallel-library

12
推荐指数
2
解决办法
2644
查看次数

使用C#/ .Net中的异步套接字安全地传输二进制数据

我们有一个用C#编写的TCP/IP套接字服务器,用于将二进制文件传输到客户端.例如,剪辑,图像.带有回调的异步BeginSend/EndSend用于发送byte []缓冲区.

新要求是加密正在传输的数据.每个客户端连接都将为服务器提供加密密钥.实际的加密算法并不重要,即目标是简单地确保数据不是以明文形式发送的.即使是带有40位密钥的RC2CryptoServiceProvider就足够了......与RC2相比,使用128位密钥的RijndaelManaged是一种过度杀伤,而且是CPU密集型的.

在传输数据文件之前,当然可以先生成加密版本的数据文件.理想情况下,我们应该在文件中读取数据并在套接字上发送时动态加密文件.给定数据文件的大小,将整个文件内容读取到内存既不高效也不可扩展.

在动态加密文件中的数据以发送到套接字对等体时,是否有一些好的模式可供遵循?

.net c# sockets cryptography asyncsocket

3
推荐指数
1
解决办法
1437
查看次数

如何为使用ilasm生成的Interop DLL设置文件版本

我们有几个C#项目通过COM Interop使用传统的COM DLL.

为了正确使用COM DLL的一些方法,我们不得不通过首先将DLL反汇编为IL,修改它,然后重新组装DLL来执行手动中间语言(IL)修改.这是一次性过程,即COM DLL不会更改.

以下是对所执行步骤的高级描述:

  1. tlbimp - 使用强名称密钥(/ keyfile参数)创建Interop*DLL
  2. ildasm - 从Interop*DLL生成中间语言(IL)
  3. 手动更改感兴趣的IL中的方法/参数
  4. ilasm - 使用与步骤1中相同的强密钥(/ key参数)重新组装DLL(/ dll参数).

然后添加生成的DLL作为对各种C#项目的引用.此DLL没有与之关联的文件版本信息,即使用"文件属性/详细信息"选项卡时.

我们希望能够设置DLL的文件版本.使用外部实用程序或手动方法(从Windows资源管理器/属性/详细信息选项卡)进行的任何尝试都会使DLL失败以前签名的文件版本.

这是我们感兴趣的普通文件版本,与COM/Interop/etc无关.理想情况下,应该在使用ilasm从IL重新组装DLL的过程中设置文件版本.

非常感谢!

.net c# com interop com-interop

3
推荐指数
1
解决办法
1083
查看次数

如何使用Powershell Get-NetFirewallRule确定Windows防火墙规则的程序路径

我们为某些程序定义了一个新的Windows防火墙规则,以接受某些端口上的入站TCP连接.这可以使用netsh.exe实用程序或Powershell New-NetFirewallRule cmdlet完成.举个例子,这是一个示例命令,允许notepad.exe接受端口5001上的TCP连接(我知道,记事本不能这样做):

New-NetFirewallRule  -program "C:\windows\System32\notepad.exe" -direction Inbound -Action Allow -Protocol tcp -LocalPort 5001 -Name "Testing Notepad on port 5001" -DisplayName "Testing Notepad on port 5001"
Run Code Online (Sandbox Code Playgroud)

要检索/查看此规则,可以再次使用netsh.exe或Get-NetFirewallRule cmdlet.

理想情况下,我们想使用Powershell Get-NetFirewallRule,但我们无法查看创建规则时使用的实际程序路径.

这是netsh.exe的输出:

netsh advfirewall firewall show rule name="Testing Notepad on port 5001" verbose

Rule Name:                            Testing Notepad on port 5001
----------------------------------------------------------------------
Enabled:                              Yes
Direction:                            In
Profiles:                             Domain,Private,Public
Grouping:
LocalIP:                              Any
RemoteIP:                             Any
Protocol:                             TCP
LocalPort:                            5001
RemotePort:                           Any
Edge traversal:                       No
Program:                              C:\windows\System32\notepad.exe
InterfaceTypes:                       Any
Security:                             NotRequired
Rule source:                          Local Setting …
Run Code Online (Sandbox Code Playgroud)

powershell windows-firewall

3
推荐指数
1
解决办法
1946
查看次数

如何将JPEG注释添加到现有JPEG图像文件

有没有办法使用libjpeg将JPEG注释("COM"标记)添加到现有的JPEG图像文件?

当然可以这样做:首先将现有图像解压缩到内存缓冲区,然后使用jpeg_write_marker(... JPEG_COM ...)再次压缩原始图像以添加注释,并保存到磁盘.除非首先需要解压缩,否则这样做似乎是一种矫枉过正.

c c++ libjpeg

2
推荐指数
1
解决办法
2479
查看次数

使用 Win32 API 列出存储在纯资源库 (DLL) 中的消息 ID 和符号名称

我们想要列出嵌入在纯资源库 (DLL) 中的消息的内容(键/值对)

资源库的定义如MSDN 中所指定。

mc -s EventLogMsgs.mc
rc EventLogMsgs.rc
link /DLL /SUBSYSTEM:WINDOWS /NOENTRY /MACHINE:x86 EventLogMsgs.Res 
Run Code Online (Sandbox Code Playgroud)

示例 EventLogMsgs.mc 可能是:

; // - Event categories -
; // Categories must be numbered consecutively starting at 1.
; // ********************************************************

MessageId=0x1
Severity=Success
SymbolicName=INSTALL_CATEGORY
Language=English
Installation
.

MessageId=0x2
Severity=Success
SymbolicName=QUERY_CATEGORY
Language=English
Database Query
.

...
Run Code Online (Sandbox Code Playgroud)

我们尝试使用 EnumResourceTypes() Win32 API,如下所示:

...
HMODULE hMod=NULL;
hMod = LoadLibraryA( "C:\\temp\\EventLogMsgs.dll" ); 
if (hMod != NULL) 
{
    EnumResourceTypes( hMod, (ENUMRESTYPEPROC)TypesCallback, 0) ;
    FreeLibrary(hMod);
}
...

BOOL …
Run Code Online (Sandbox Code Playgroud)

c++ dll winapi visual-c++

2
推荐指数
1
解决办法
1164
查看次数