2010-05-17 2 views
3

반영된 일반 대리자를 호출하는 동안 이상한 일이 발생했습니다. 일부 디버거가있는 경우에는 불가능한 호출을 할 수 있지만 디버거가 없으면 어떤 예외 나 응용 프로그램을 빠뜨릴 수 없습니다.디버거가 있거나없는 반사 된 일반 대리인의 다른 동작

  1. 행동은 디버거와 당신은 CLR 트릭에 의해 디버거없이이 오류를 잡을 수 없어
  2. 없이 다릅니다

    using System; 
    using System.Windows.Forms; 
    using System.Reflection; 
    
    namespace GenericDelegate 
    { 
        public partial class Form1 : Form 
        { 
         public Form1() 
         { 
          InitializeComponent(); 
         } 
    
         private delegate Class2 Delegate1(); 
    
         private void button1_Click(object sender, EventArgs e) 
         { 
          MethodInfo mi = typeof (Class1<>).GetMethod("GetClass", BindingFlags.NonPublic | BindingFlags.Static); 
          if (mi != null) 
          { 
           Delegate1 del = (Delegate1) Delegate.CreateDelegate(typeof (Delegate1), mi); 
           MessageBox.Show("1"); 
           try 
           { 
            del(); 
           } 
           catch (Exception) 
           { 
            MessageBox.Show("No, I can`t catch it"); 
           } 
           MessageBox.Show("2"); 
           mi.Invoke(null, new object[] {});//It's Ok, we'll get exception here 
           MessageBox.Show("3"); 
          } 
         } 
    
    
         class Class2 
         { 
    
         } 
    
    
         class Class1<T> : Class2 
         { 
          internal static Class2 GetClass() 
          { 
           Type type = typeof(T); 
           MessageBox.Show("Type name " + type.FullName +" Type: " + type + " Assembly " + type.Assembly); 
           return new Class1<T>(); 
          } 
         } 
        } 
    } 
    

    이 두 가지 문제가 있습니다 : 여기

    는 코드입니다. 그것은 단지 clr 예외가 아닙니다. 내부 코드 내부에 0 포인터를 읽는 메모리 액세스 바이 얼레이션이 있습니다.

사용 사례 : 앱용 플러그인 시스템과 같은 것을 개발합니다. 당신은 외부 어셈블리를 읽고, 어떤 타입에서 적절한 메소드를 찾아 그것을 실행합니다. 그리고 우리는 점검 할 필요가 있다는 것을 잊어 버렸습니다. VS에서 (그리고 2.0에서 4.0까지의 .net) 모든 것이 잘 동작합니다. 호출 된 함수는 제네릭 형식 및 형식 매개 변수의 정적 컨텍스트를 사용하지 않습니다. 그러나 VS 응용 프로그램이 없어도 소리가 들리지 않습니다. 호출 스택에 연결된 디버거도 식별 할 수 없습니다. VS 어획량하지만 런타임이하지 않는 이유

는 .NET과 테스트 4.0

질문은?

답변

2

입니다. .NET 4.0에서 부분적으로 수정되었으며 CreateDelegate() 메서드는 null을 반환합니다. JIT 옵티 마이저가 활성화되었을 때 여전히 정상적으로 작동하지 않지만 CreateDelegate가 null을 리턴 할 수없고 널 (null) 점검을 수행하지 않는다고 가정합니다. 4.0에서 더 이상 catch 할 수없는 예외 인 NRE 대신 FatalExecutionEngineError가 표시됩니다.

connect.microsoft.com에 결함을보고하는 것이 좋습니다. 그들이 당신을 진지하게 받아 들일 것이라고 확신하지는 않습니다. 의도적으로 안전 장치를 우회 할 때 그들의 정책이 무엇인지 모르겠습니다. FEEE가 충분히 좋다고 생각할 수도 있습니다. 해결 방법은 명백합니다. 구체적인 유형의 메소드 만 호출하십시오.

1

정확히 무엇을하고 싶은지 잘 모르겠지만 try/catch 블록에 코드를 넣으면 확실히 예외가 발생합니다.

+0

어떤 경우에는 del();을 호출하는 몇 가지 정보가 있습니다. "불완전한 객체 그래프가있는 객체"와 같은 예외를 발생시킵니다. 하지만 내 컴퓨터에서는 그렇지 않습니다. –

+1

불행히도 4.0에서 시도 할 수 없지만 VS2005/2.0에서 Application.Run 문에 대한 호출을 try/catch하면 예외가 발생합니다. 그래도 문제가 해결되지는 않습니다. –

+0

VS의 디버거가 "del(); 프로세스 함수에 첨부되어있는 경우 그것이 실행되어서는 안되는 동안 실행됩니다. 형식 매개 변수가 지정되지 않았으므로 실패해야합니다. 디버거가 연결되어 있지 않으면 clr 예외없이 프로세스가 종료됩니다. –

1

VS 2008에서 바로 테스트했습니다. VS가 예외를 전혀 잡지 못합니다. 여기
는 테스트 케이스를

static class Program 
    { 
     private delegate Foo Delegate1(); 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 

      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      MethodInfo mi = typeof(Bar<>).GetMethod("GetClass", BindingFlags.NonPublic | BindingFlags.Static); 
      if (mi != null) 
      { 
       var del = (Delegate1)Delegate.CreateDelegate(typeof(Delegate1), mi); 

       MessageBox.Show("1"); 
       try 
       { 
        del(); 
        //mi.Invoke(null, BindingFlags.NonPublic | BindingFlags.Static, null, null,CultureInfo.InvariantCulture); 
       } 
       catch (Exception) 
       { 
        MessageBox.Show("No, I can`t catch it"); 
       } 
       MessageBox.Show("2"); 
       mi.Invoke(null, new object[] { });//It's Ok, we'll get exception here 
       MessageBox.Show("3"); 
      } 
     } 
     class Foo 
     { 

     } 
     class Bar<T> : Foo 
     { 
      internal static Foo GetClass() 
      { 
       Type type = typeof(T); 
       MessageBox.Show("Type name " + type.FullName + " Type: " + type + " Assembly " + type.Assembly); 
       return new Bar<T>(); 
      } 
     } 
    } 

을 수정하지만) 싶게 주석 mi.Invoke을 델을 (언급하는 경우() 당신은 좋은 예외가
사실 얻을 것이다.

늦은 바인딩 작업이 이 하는 ContainsGenericParameters에 대한 유형이나 방법을 수행 할 수 없습니다 것은 글쎄, 그래, 아주 정상적으로 작동하지 않습니다 사실

1

내가 게시 한 코드가 실제로 .net 프레임 워크에서 작동한다고 생각하지 않습니다. 2.0에서 4.0. 정적 메서드는 열린 일반 형식이 아닌 닫힌 제네릭 형식에 대해서만 AFAIK라고 부를 수 있습니다. 따라서 유형 매개 변수를 제공해야합니다. 디버거에 대해서는 Visual Studio 외부에서 프로세스를 시작한 다음 VS-Debugger를 연결하십시오.이번에는 예상되는 예외를 바로 잡을 것입니다.

+0

>> "형식 매개 변수를 입력해야합니다." 예. 형식 매개 변수를 제공해야합니다. 나는하지 않았다. 깜빡했습니다. 아니면 제네릭 유형을 처리 할지도 몰랐습니다. 그리고 코드가 작동합니다. –

관련 문제