무료 .NET dll 디컴파일 프로그램 dotPeek


https://www.jetbrains.com/decompiler/

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

RollingFileAppender class

addFilter

public void addFilter(Filter newFilter)
Add a filter to end of the filter list.

Specified by:
addFilter in interface Appender


위 filter에 log level을 설정할 수 있는데 검색하다 발견한 내용들.


 ALL    DEBUG   INFO    WARN    ERROR   FATAL   OFF
All                        
DEBUG  DEBUG                  
INFO   INFO   INFO               
WARN   WARN   WARN   WARN           
ERROR  ERROR  ERROR  ERROR  ERROR      
FATAL  FATAL  FATAL  FATAL  FATAL  FATAL  
OFF    OFF    OFF    OFF    OFF    OFF    OFF

위와 같은 모양으로 되어 있는 것으로 설정을 해봤다. 


LevelMinLevelMax를 All로 지정하면 모두가 나올 줄 알았지만 나오지 않았다.

LevelMin을 DEBUG, LevelMax를 ERROR로 테스트를 할 경우 위에  조건대로 로그가 생성되는 것을 확인하였다. 


로그가 생성이 안된다고 Log4Net이 문제라 생각하지말고 레벨 설정, 파일 경로 등을 설정해보라.


참고 : https://stackoverflow.com/questions/8926409/log4net-hierarchy-and-logging-levels

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

    "_id" : ObjectId("5bee629dee0fc9d332b2107b"), 

    "no" : NumberLong(30001), 

    "name" : "레몬과일가게", 

    "products" : [

        {

            "id" : NumberLong(50001), 

            "name" : "레몬", 

            "price" : NumberInt(4), 

        }, 

        {

            "id" : NumberLong(50002), 

            "name" : "사과", 

            "price" : NumberInt(12), 

        }, 

        {

            "id" : NumberLong(50003), 

            "name" : "파인애플", 

            "price" : NumberInt(3), 

        }, 

        {

            "id" : NumberLong(50004), 

            "name" : "귤", 

            "price" : NumberInt(3), 

        }

    ]

mongodb 에서   30001번 과일가게에서 레몬의 가격을 변경하기 위한 코드 샘플

var filter = Builders<store>.Filter.Where(c => c.no == 30001 && c.products.Any(e => e.id == 50001));

var update = Builders<player>.Update.Set(x => x.products[-1].price, 2000);

var option = new UpdateOptions() { IsUpsert = false }; 


출처 : https://stackoverflow.com/questions/31453681/mongo-update-array-element-net-driver-2-0


https://stackoverflow.com/questions/31277679/how-to-find-and-update-an-item-inside-of-a-array-of-an-object-in-an-array-acc

블로그 이미지

레몬도리 LemonDory

개발자의 이야기


mongodb collection을 protobuf class로 가져오려고 하던 중에 List 형태를 가져와보려고 많은 시간을 소비해 가며 보던 중에 .proto로 gen할 때 자세히 보니 repeated 값들이 readonly로 생성 되는 것을 보았다.


여기 저기 검색하던 중에 protobuf를 본 외국인의 글을 발견했다.(질문자는 다른 방법이 필요했던 거였지만 아래 더 자세한 설명을 해준 답변자의 답변이 눈에 들어왔다)

링크 : https://stackoverflow.com/questions/16617933/protobuf-net-generated-class-from-proto-is-repeated-field-supposed-to-be-re


This was a new issue for us as well after updating our proto-net executable and related files. It was new behavior we hadn't experienced before.

After a little digging in csharp.xslt, we found the definition for 'repeated' fields:

<xsl:template match="FieldDescriptorProto[label='LABEL_REPEATED']">
    <xsl:variable name="type"><xsl:apply-templates select="." mode="type"/></xsl:variable>
    <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable>
    <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable>
    private <xsl:if test="not($optionXml)">readonly</xsl:if> global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:value-of select="$field"/> = new global::System.Collections.Generic.List&lt;<xsl:value-of select="$type"/>&gt;();
    [<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, Name=@"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/><xsl:if test="options/packed='true'">, Options = global::ProtoBuf.MemberSerializationOptions.Packed</xsl:if>)]<!--
    --><xsl:if test="$optionDataContract">
    [global::System.Runtime.Serialization.DataMember(Name=@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = false)]
    </xsl:if><xsl:if test="$optionXml">
    [global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)]
    </xsl:if>
    public global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:call-template name="pascal"/>
    {
      get { return <xsl:value-of select="$field"/>; }<!--
      --><xsl:if test="$optionXml">
      set { <xsl:value-of select="$field"/> = value; }</xsl:if>
    }
  </xsl:template>

I've pulled out the specific parts for the private field and the setter:

private <xsl:if test="not($optionXml)">readonly</xsl:if> ...snip...

public ...snip...
{
  ...snip... 
  <!----><xsl:if test="$optionXml">
  set { <xsl:value-of select="$field"/> = value; }
  </xsl:if>
}

Notice the suspect conditions above for $optionXml. If you just remove those, the field is no longer readonly and the setter is properly generated.

So it then becomes: private ...snip...

public ...snip...
{
  ...snip... 
  set { <xsl:value-of select="$field"/> = value; }
}

Full 'fixed' template:

  <xsl:template match="FieldDescriptorProto[label='LABEL_REPEATED']">
    <xsl:variable name="type"><xsl:apply-templates select="." mode="type"/></xsl:variable>
    <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable>
    <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable>
    private global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:value-of select="$field"/> = new global::System.Collections.Generic.List&lt;<xsl:value-of select="$type"/>&gt;();
    [<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, Name=@"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/><xsl:if test="options/packed='true'">, Options = global::ProtoBuf.MemberSerializationOptions.Packed</xsl:if>)]<!--
    --><xsl:if test="$optionDataContract">
    [global::System.Runtime.Serialization.DataMember(Name=@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = false)]
    </xsl:if><xsl:if test="$optionXml">
    [global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)]
    </xsl:if>
    public global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:call-template name="pascal"/>
    {
      get { return <xsl:value-of select="$field"/>; }
      set { <xsl:value-of select="$field"/> = value; }
    }
  </xsl:template>

I played with setting optionXml to false, but it didn't work and you may still want that option enabled anyway.


위와 마지막 fixed template을 보고 protogen.exe 폴더에 있는 csharp.xslt의 내용을 수정하면 될 것이다.

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

HttpListener를 사용하여 개발 중에 서버포트로 연결이 불가하다는 메시지로 Exception이 떨어지는 현상이 발생하여 찾아본 명령어


명령 프롬프트(관리자 권한)를 열고 아래 명령어에 포트만 변경하여 실행하고 실행해보자


netsh http add urlacl url=http://*:8888/ user=Everyone listen=yes 


아래 참고 블로그를 링크 걸어놓는다.


참고 : http://www.windowcmc.com/q.php?q=netsh-http-kr-manual

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

출처 : https://nabacg.wordpress.com/2013/05/13/gc-background-vs-concurrent-mode/


번역이며 오역이 있을 수 있습니다.


저는 최근 .NET에서 Garbage Collection에 대해 많은 것을 읽었습니다. 프로젝트 중 하나에서 메모리 누출을 연구하고 점점 더 많은 MSDN 기사를 읽었습니다. 놀랍게도 지난 번에 주제에 대해 괴롭힘을당한 이후로이 지역에 새로운 개발이 많이있었습니다. 그래서 다른 사람들이 유용하다고 생각할 때 나중에 참조 할 수 있도록 그들을 요약 해 보겠습니다. 이 MSDN 기사 에서 CLR의 현재 GC 상태에 대한 개요를 찾을 수 있으므로 자유롭게 시작할 수 있습니다.

워크 스테이션 대 서버

실제로 두 가지 모드 가비지 콜렉션이 있습니다.이 모드는 구성 파일의 런타임 구성 부분에서 gcServer 태그를 사용하여 제어 할 수 있습니다. 워크 스테이션 가비지 콜렉션은 기본적으로 gcServer = "true"로 설정하더라도 단일 프로세서 시스템에서 항상 사용됩니다.

1
2
4
5
<configuration>
   <runtime>
      <gcServer enabled="true|false"/>
   </runtime>
</configuration>

그 모드는 실제로 꽤 오래되었습니다. gcServer 태그는 .NET 2.0에 도입되었으며 따라서 CLR의 두 번째 버전입니다. 주요 차이점은 서버 모드에서 GC를 수행하는 스레드가 1 개 이상 있고 모두 THREAD_PRIORITY_HIGHEST 우선 순위 수준 에서 실행 된다는 것 입니다. GC 전용 스레드와 각 CPU에 대한 별도의 힙 (일반 및 대형 오브젝트 모두)이 있으며 이들 모두는 동시에 수집됩니다. 여기서 우선 순위가 높은 여러 스레드를 사용하여 최대한 빨리 컬렉션을 만들려고하지만 모든 사용자 스레드가 준비 될 때까지 일시 중지해야한다는 것을 의미합니다. 일반적으로 응답 속도보다 처리량이 높은 서버 응용 프로그램에 더 적합합니다. 이는 일반적인 데스크톱 응용 프로그램의 경우가 아닙니다. 서버 모드는 리소스를 많이 소비 할 수도 있습니다.

동시 vs 백그라운드
서버 vs 워크 스테이션 외에도 동시 및 백그라운드 작업 모드가 있습니다. 둘 다 사용하면 모든 사용자 스레드를 일시 중지하지 않고 전용 스레드가 2 세대를 수집 할 수 있습니다. 0 세대와 1 세대는 모든 사용자 스레드를 일시 중지해야하지만 항상 빠릅니다. 이는 물론 애플리케이션이 제공 할 수있는 대응 수준을 높입니다. 실제 모드는 다양하며 서버 대 워크 스테이션 유형의 GC에 따라 달라질 수 있습니다. 다음 섹션에서 자세히 설명합니다. 조금 혼란 스러울 수 있으므로 아래에서 가능한 모든 조합을 찾을 수 있습니다.

워크 스테이션 가비지 수집은 다음과 같습니다.

  • 병발 사정
  • 배경
  • 비 동시성

서버 가비지 수집 옵션은 다음과 같습니다.

  • 배경
  • 비 동시성

동시 모드
Workstation GC의 기본 모드이며 다중 프로세서 시스템에서도 GC를 수행하는 전용 스레드를 제공합니다. gcConcurrent 태그 를 사용하여 끌 수 있습니다 .

1
2
4
5
<configuration>
   <runtime>
      <gcConcurrent enabled="true|false"/>
   </runtime>
</configuration>

이 모드는 병행 GC 동안 제한된 할당 기능을 희생시켜 가장 많은 시간을 소비하는 Gen2 수집이 동시에 수행되므로 사용자 스레드 일시 중지가 훨씬 짧아집니다. Gen2 수집이 진행되는 동안 다른 스레드는 새로운 임시 메모리 세그먼트를 할당 할 수 없기 때문에 현재 임시 세그먼트의 한도까지만 할당 할 수 있습니다. 현재 세그먼트에서 프로세스가 제대로 실행되지 않으면 모든 스레드를 일시 중지하고 동시 수집이 완료 될 때까지 기다려야합니다. 동시 GC가 아직 진행 중일 때 Gen0 및 Gen1 컬렉션을 수행 할 수 없기 때문입니다. 또한 동시 GC에는 약간 더 높은 메모리 요구 사항이 있습니다.

백그라운드 모드 .NET 4.0
에는 새로운 백그라운드 모드가 도입되었습니다.이 모드는 동시 모드와 비슷한 개념을 가지고 있지만, 동시 모드를 대체해야하기 때문에 기본적으로 설정되어 있습니다. Concurrent는 Workstation에서만 사용할 수있는 반면 Workstation 및 Server 모드에서도 사용할 수 있습니다. 배경 모드가 실제로 Gen2 및 Gen1 컬렉션을 수행하면서 동시에 Gen2를 수행 할 수 있다는 큰 개선점이 있습니다. 이제 gen0, gen1 모음을 전경 모음이라고합니다. 사용자 스레드가 실행 중일 때 별도의 스레드에 의해 2 세대 콜렉션 만 수행되고, 포 그라운드 콜렉션은 모든 사용자 스레드를 일시 중지해야합니다. 또한 전경 컬렉션에는 배경 컬렉션에서 일시 중지가 필요하며, 그래서 그들은 다양한 안전 포인트를 통해 서로 상호 작용합니다. 백그라운드 컬렉션은 서버 GC에서 사용할 수 있으며 .NET 4.5로 시작하는 기본 모드입니다. 서버와 워크 스테이션 백그라운드 모드의 주요 차이점은 백그라운드 GC를 수행하는 스레드의 수입니다. 워크 스테이션에서는 항상 단일 스레드이고 서버 GC에서는 CPU 당 전용 스레드가 있습니다.

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

변수명 찾기 

http://stackoverflow.com/questions/9801624/get-name-of-a-variable-or-parameter

변수명 찾기, 변수 값 가져오기

https://blogs.msdn.microsoft.com/csharpfaq/2010/03/11/how-can-i-get-objects-and-property-values-from-expression-trees/

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

출처 : https://msdn.microsoft.com/ko-kr/library/bb384067.aspx

 

where(제네릭 형식 제약 조건)(C# 참조)

제네릭 형식 정의에서 where 절은 제네릭 선언에 정의된 형식 매개 변수의 인수로 사용할 수 있는 형식에 대해 제약 조건을 지정하는 데 사용됩니다. 예를 들어, 다음과 같이 형식 매개 변수 TIComparable<T> 인터페이스를 구현하도록 제네릭 클래스 MyGenericClass를 선언할 수 있습니다.
public class MyGenericClass<T> where T:IComparable { }
System_CAPS_note참고

쿼리 식의 where 절에 대한 자세한 내용은 where 절(C# 참조)을 참조하십시오.

where 절에는 인터페이스 제약 조건 외에 기본 클래스 제약 조건도 포함될 수 있습니다. 이 제약 조건은 지정된 클래스를 기본 클래스로 갖거나 지정된 클래스 자체인 형식만 해당 제네릭 형식의 형식 인수로 사용할 수 있도록 제한합니다. 이러한 제약 조건을 사용할 경우에는 해당 형식 매개 변수에 대한 다른 모든 제약 조건 앞에 사용해야 합니다.  

class MyClass<T, U>
    where T : class
    where U : struct
{ }

where 절에는 생성자 제약 조건도 포함될 수 있습니다. new 연산자를 사용하여 형식 매개 변수의 인스턴스를 만들 수 있지만, 이렇게 하려면 형식 매개 변수를 생성자 제약 조건 new()로 제한해야 합니다. new() 제약 조건을 사용하면 컴파일러에서는 제공된 모든 형식 인수가 액세스 가능하고 매개 변수 없는(또는 기본) 생성자를 가져야 한다는 것을 알 수 있습니다. 예를 들면 다음과 같습니다.

public class MyGenericClass<T> where T : IComparable, new()
{
    // The following line is not possible without new() constraint:
    T item = new T();
}

new() 제약 조건은 where 절의 마지막에 나와 있습니다.

형식 매개 변수가 여러 개이면 다음 예제와 같이 where 절을 각 형식 매개 변수마다 하나씩 사용합니다.

interface IMyInterface
{
}

class Dictionary<TKey, TVal>
    where TKey : IComparable, IEnumerable
    where TVal : IMyInterface
{
    public void Add(TKey key, TVal val)
    {
    }
}
다음과 같이 제네릭 메서드의 형식 매개 변수에 제약 조건을 연결할 수도 있습니다.

public bool MyMethod<T>(T t) where T : IMyInterface { }

 

 

대리자에 대한 형식 매개 변수 제약 조건을 설명하기 위한 구문은 메서드에 사용하는 구문과 동일합니다.

delegate T MyDelegate<T>() where T : new()

제네릭 대리자에 대한 자세한 내용은 제네릭 대리자를 참조하십시오.

제약 조건의 구문 및 사용 방법에 대한 자세한 내용은 형식 매개 변수에 대한 제약 조건을 참조하십시오.

블로그 이미지

레몬도리 LemonDory

개발자의 이야기

티스토리 툴바