小编Rom*_*ier的帖子

ServerGC应用程序中的GC线程计数非常高

TL; DR:支持服务器GC的应用程序显示数十个特殊的GC线程并超时挂起.有什么可以解释的?


这些天我一直处于.NET服务上出现的奇怪的多线程/争用问题上.症状如下:

  • 程序挂起很长一段时间(几秒到几分钟)
  • 线程数异常高
  • 当程序停止响应时,存在争用的高峰(参见下图)
  • 相同的程序部署在不同的服务器上,有些实例根本没有问题(相同的硬件/ OS/CLR)

争论高峰

我立即怀疑我们的代码中存在一个问题,该问题会导致托管线程池随着时间的推移启动大量线程,所有这些都试图共享一个或多个公共资源.似乎我们对ThreadPool的使用非常小并且非常有用.

我设法获得一个非挂起服务的转储文件,该服务已经拥有非常多的线程(超过100,在正常状态下它应该是20左右)

使用windbg + sos,我们确定ThreadPool大小正常:

0:000> !threadpool
CPU utilization: 0%
Worker Thread: Total: 8 Running: 1 Idle: 7 MaxLimit: 32767 MinLimit: 32
Work Request in Queue: 0
--------------------------------------
Number of Timers: 1
--------------------------------------
Completion Port Thread:Total: 1 Free: 1 MaxFree: 64 CurrentLimit: 1 MaxLimit: 1000 MinLimit: 32
Run Code Online (Sandbox Code Playgroud)

只有8个工作线程......然后我列出了所有托管线程堆栈,发现了很多我无法识别的线程堆栈.请参阅下面的一个示例:

0:000> !eestack
(...)
Thread  94
Current frame: ntdll!NtWaitForSingleObject+0xa
Child-SP         RetAddr          Caller, Callee
0000008e25b2f770 000007f8f5a210ea KERNELBASE!WaitForSingleObjectEx+0x92, calling ntdll!NtWaitForSingleObject
0000008e25b2f810 000007f8ece549bf clr!CLREventBase::WaitEx+0x16c, calling …
Run Code Online (Sandbox Code Playgroud)

.net clr multithreading garbage-collection windbg

8
推荐指数
1
解决办法
1266
查看次数

ILGenerator周围有一个很好的包装器吗?

我现在使用System.Reflection.Emit一段时间了,发现它(谁没有?)像容易出错一样痛苦.

你知道IL Generator周围是否有一个好的包装器,我可以依赖它以比直接使用SRE更安全,更容易的方式发出IL吗?

编辑:

我知道操纵表达树比直接发射IL更容易和更安全,但它们现在也有一些限制.我不能创建代码块,使用循环,声明和使用几个本地,等等.我们需要等到.NET 4出来:)

此外,我正在处理已经依赖于SRE的代码库.

显然,ILGenerator会做我需要的一切.但是在操纵它时我会感激更多的帮助.当我指的是一个非常低级别的ILGenerator包装器时,我想到的东西可以提供如下方法:

// Performs a virtual or direct call on the method, depending if it is a 
// virtual or a static one.
Call(MethodInfo methodInfo)

// Pushes the default value of the type on the stack, then emit 
// the Ret opcode.
ReturnDefault(Type type)

// Test the object type to emit the corresponding push 
// opcode (Ldstr, Ldc_I*, Ldc_R*, etc.)
LoadConstant(object o)
Run Code Online (Sandbox Code Playgroud)

这真的是3个天真的例子,但它足以证明我的期望.我们可以看到它作为一组扩展方法,但是在RunSharp中支持条件语句和循环可能会很好.实际上,RunSharp与我想要的非常接近,但它过多地抽象了ILGenerator并且没有公开它的所有功能.

我不记得在哪里,但我已经在开源项目中看到过这样的帮手.

.net c# cil ilgenerator

7
推荐指数
1
解决办法
3547
查看次数

将连续的相同项分组:IEnumerable <T>到IEnumerable <IEnumerable <T >>

我有一个有趣的问题:给定一个IEnumerable<string>,是否有可能IEnumerable<IEnumerable<string>>在一次传递中产生一组相同的相邻字符串?

让我解释.

1.基本说明性样本:

考虑以下IEnumerable<string>(伪表示):

{"a","b","b","b","c","c","d"}
Run Code Online (Sandbox Code Playgroud)

如何获得一个IEnumerable<IEnumerable<string>>会产生某种形式的东西:

{ // IEnumerable<IEnumerable<string>>
    {"a"},         // IEnumerable<string>
    {"b","b","b"}, // IEnumerable<string>
    {"c","c"},     // IEnumerable<string>
    {"d"}          // IEnumerable<string>
}
Run Code Online (Sandbox Code Playgroud)

方法原型将是:

public IEnumerable<IEnumerable<string>> Group(IEnumerable<string> items)
{
    // todo
}
Run Code Online (Sandbox Code Playgroud)

但它也可能是:

public void Group(IEnumerable<string> items, Action<IEnumerable<string>> action)
{
    // todo
}
Run Code Online (Sandbox Code Playgroud)

...... action每个子序列都会被调用.

2.更复杂的样本

好的,第一个样本非常简单,只是为了使高级意图清晰.

现在假设我们正在处理IEnumerable<Anything>,在这里Anything定义的类型如下:

public class Anything
{
    public string Key {get;set;}
    public double Value {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我们现在想要生成基于Key的子序列(Anything将具有相同键的每个连续组分组)以便稍后使用它们以便按组计算总值:

public void Compute(IEnumerable<Anything> items) …
Run Code Online (Sandbox Code Playgroud)

c# algorithm performance ienumerable

7
推荐指数
1
解决办法
1443
查看次数

如何使用NAnt 0.86 beta运行NUnit v2.4.8测试?

我最近尝试使用NAnt(beta 0.86.2962.0)运行一些使用NUnit(v2.4.8)的最后一个稳定版本编译的单元测试,但没有任何成功.

我得到的错误如下:

[nunit2]程序集"C:\ Dev\MySample\bin\tests\My.Sample.Tests.dll"不包含任何测试.

当然,程序集包含可以从任何运行程序运行的测试,例如NUnit one,TestDriven或Resharper.我想使用<nunit2>任务,而不是直接使用<exec>,但我想知道它是否仍然可行,甚至使用app.config文件来绑定程序集版本.

.net nant nunit unit-testing

6
推荐指数
1
解决办法
2232
查看次数

使用WCF在Silverlight中共享服务接口和模型

假设我有以下界面,我想在我的服务器(常规Web服务)和我的客户端(silverlight 2.0应用程序)之间共享:

public interface ICustomerService
{
    Customer GetCustomer(string name);
}
Run Code Online (Sandbox Code Playgroud)

我的Web服务实现了这个接口,并引用了一个Customer定义了类型的类库.

通常,如果您想从WCF客户端(例如winforms应用程序)使用此服务,则可以共享模型程序集和服务合同接口.然后,通过使用a ChannelFactory,您可以动态创建实现服务接口的代理.就像是:

ICustomerService myService = new ChannelFactory<ICustomerService>(myBinding, myEndpoint);
Customer customer = myService.GetCustomer("romain");
Run Code Online (Sandbox Code Playgroud)

我基本上想要做同样的事情,但是从Silverlight 2.0应用程序.银光ChannelFactory似乎不像另一个......

你知道这是否可能?

注意:由于Silverlight应用程序只能引用Silverlight项目,因此我有:

两个版本的MyModel.dll包含Customer类型:

  • 一个编译目标.NET框架3.5,由我的Web服务项目引用
  • 另一个编译目标是silverlight 2.0框架,由我的silverlight app引用

两个版本的MyServicesContracts.dll包含ICustomerService接口:

  • 一个编译目标.NET框架3.5,由我的Web服务项目引用
  • 另一个编译目标是silverlight 2.0框架,由我的silverlight app引用

.net c# silverlight wcf

5
推荐指数
1
解决办法
3344
查看次数

"静态反射"在java中如何工作?(例如在mockito或easymock中)

我是一个.NET人 - 我主要使用C#编写代码.

从C#3.0开始,我们可以利用lambda表达式和表达式树来使用静态反射.例如,可以GetMethodName在以下代码段中实现返回参数中传递的方法的名称:

string methodName = GetMethodName( o => o.DoSomething());
Console.WriteLine(methodName); // displays "DoSomething"
Run Code Online (Sandbox Code Playgroud)

现在,当我在Java世界中查看Mockito样本(或EasyMock样本)时,我看到:

LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");
Run Code Online (Sandbox Code Playgroud)

它是如何工作的?

when方法如何工作?它mockedList.get(0)是如何解释为对get方法的调用,0作为参数而不是作为值传递

c# java reflection easymock mockito

5
推荐指数
1
解决办法
2001
查看次数

使用自定义十进制原型契约(C#/ C++互操作)时,使用Protobuf-net(de)序列化小数

假设我想序列化,然后使用protobuf-net反序列化小数:

const decimal originalDecimal = 1.6641007661819458m;
using (var memoryStream = new MemoryStream())
{
    Serializer.Serialize(memoryStream, originalDecimal);
    memoryStream.Position = 0;
    var deserializedDecimal = Serializer.Deserialize<decimal>(memoryStream);
    Assert.AreEqual(originalDecimal, deserializedDecimal);
}
Run Code Online (Sandbox Code Playgroud)

它工作正常.Protobuf-net内部使用以下小数表示(参见Bcl.proto):

message Decimal {
  optional uint64 lo = 1; // the first 64 bits of the underlying value
  optional uint32 hi = 2; // the last 32 bis of the underlying value
  optional sint32 signScale = 3; // the number of decimal digits, and the sign
}
Run Code Online (Sandbox Code Playgroud)

现在说我用代码定义了一个假定的等价原型合约:

[ProtoContract]
public class MyDecimal
{ …
Run Code Online (Sandbox Code Playgroud)

c# c++ decimal protocol-buffers protobuf-net

5
推荐指数
1
解决办法
1837
查看次数

C#中需要某种创作模式

我有以下类型:

// incomplete class definition
public class Person
{
    private string name;

    public string Name
    {
        get { return this.name; }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望使用某种专用控制器/构建器创建更新此类型,但我希望它对其他类型保持只读.

每次由控制器/构建器更新事件时,此对象还需要触发事件.

总结一下,根据以前的类型定义骨架:

  • Person只能通过特定的控制器被实例化
  • 该控制器可以随时更新Person(name字段)的状态
  • Person需要一个发送通知到世界其他地方发生时
  • 所有其他类型应该只能读取 Person属性

我该如何实现呢?我在这里谈论的是控制器/构建器,但欢迎所有其他解决方案.

注意:我可以依赖internal修饰符,但理想情况下我的所有东西都应该在同一个程序集中.

.net c# design-patterns

4
推荐指数
1
解决办法
472
查看次数

在Sourceforge上将OSS项目许可从GPL切换到L-GPL

是否可以将开源项目许可证从GPL切换到LGPL v3

我是项目的创始人,也是唯一的贡献者.

licensing open-source

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