2010-06-24 35 views
5

Phân tích
"System.Reflection.TargetException: Object không khớp với loại mục tiêu." khi gọi MethodBase.Invoke trong một derivate của RealProxy. Sự cố xuất hiện đột ngột và không có bất kỳ lý do rõ ràng nào trong nhật ký cam kết svn hoặc nhật ký sự kiện máy chủ.Hệ thống không mong muốn .__ Canon có độ phản chiếu

Kịch bản
Windows Server 2008 R2 Standard, 64 bit
Microsoft .NET Framework Version: 2.0.50727.4927
ASP.NET Version: 2.0.50727.4927
ứng dụng IIS hồ chạy trong chế độ đường ống tích hợp.
Khuôn khổ .NET 4.0 được cài đặt NOT.

Đây là một số mẫu được nén để hiển thị luồng mã nơi sự cố này xảy ra. Tôi đã loại bỏ rất nhiều đăng nhập, hợp đồng, vv, chỉ để giữ mã ngắn cho bài đăng này.

// Interface structure 
ICommentRepository : IRepository<Comment> 
IRepository<T> : IRepositoryWithTypedId<T, Guid> 
IRepositoryWithTypedId<T, TId> 
    void Delete(T item); 

// Extract from ServicesProvider which instantiates the proxies. 
public class ServicesProvider { 
    public T GetService<T>() where T : class { 
     var proxy = WcfProxyFactory<T>.OpenChannel(); 
     proxy = ApplyLoggingProxy(proxy); 
     return proxy; 
    } 

    private static T ApplyLoggingProxy<T>(T instance) where T : class { 
     return (T)new LoggingProxy<T>(instance).GetTransparentProxy(); 
    } 
} 

public class LoggingProxy<T> : ProxyBase<T> where T : class { 
    public LoggingProxy(T instance) 
     : base(instance) { 
    } 

    protected override IMethodReturnMessage InvokeMethodCall(IMethodCallMessage msg) { 
     var methodName = String.Format("{0}.{1}", InstanceType.Name, msg.MethodName); 
     // methodName = "ICommentRepository.Delete" 

     var methodCall = ReflectionHelper.GetMethodCall(msg); 
     // methodCall = "IRepositoryWithTypedId<__Canon, Guid>.Delete(...)" 

     Trace.WriteCategory(methodName, "Calling {0}", methodCall); 

     return base.InvokeMethodCall(msg); 
    } 
} 

public abstract class ProxyBase<T> : RealProxy where T : class { 
    protected static readonly Type InstanceType = typeof(T); 
    protected readonly T Instance; 
    protected readonly ITraceWriter Trace = new HttpContextTraceWriter(); 

    protected ProxyBase(T instance) { 
     Instance = instance; 
    } 

    public override IMessage Invoke([NotNull] IMessage msg) { 
     var methodCallMessage = msg as IMethodCallMessage; 
     if (methodCallMessage != null) 
      return InvokeMethodCall(methodCallMessage); 

     throw new NotImplementedException("Unknown message type"); 
    } 

    protected virtual IMethodReturnMessage InvokeMethodCall([NotNull] IMethodCallMessage msg) { 
     var args = msg.Args; 
     var result = msg.MethodBase.Invoke(Instance, args); 
     return new ReturnMessage(result, args, msg.ArgCount, msg.LogicalCallContext, msg); 
    } 
} 

// Line causing the error. 
servicesProvider.GetService<ICommentRepository>().Delete(...); 

nổi bật
Tôi đã thêm một số lỗi vào LoggingProxy.InvokeMethodCall, đặc biệt viết ra tất cả các thuộc tính của msg.Method (khai báo là MethodBase, là RuntimeMethodInfo) và msg.Method.DeclaringType. Tôi sẽ cung cấp một số điểm nổi bật kỳ lạ.

  • method.Attributes = (PrivateScope | Công | ảo | HideBySig | VtableLayoutMask | Tóm tắt), PrivateScope nghĩa "Chỉ ra rằng các thành viên không thể được tham chiếu" Tôi khá chắc chắn rằng tôi có một tham chiếu đến nó. ;)
  • method.DeclaringType = "IRepositoryWithTypedId`2 [Hệ thống .__ Canon, System.Guid]"
  • method.ReflectedType = "IRepositoryWithTypedId`2 [Hệ thống .__ Canon, System.Guid]"
  • type.FullName = "IRepositoryWithTypedId`2 [[Hệ thống .__ Canon, mscorlib, Phiên bản = 2.0.0.0, Văn hóa = trung lập, PublicKeyToken = b77a5c561934e089], [System.Guid, mscorlib, Version = 2.0.0.0, Culture = neutral , PublicKeyToken = b77a5c561934e089]] "
  • type.UnderlyingSystemType =" IRepositoryWithTypedId`2 [Sy ngăn chặn .__ Canon, System.Guid]"
  • type.GenericArguments [0] = typeof (__Canon)

Tôi không có ý tưởng thế nào điều này xảy ra, và làm thế nào để giải quyết nó. Một số tìm kiếm google cung cấp gợi ý vô hiệu hóa nội tuyến của phương thức (MethodImplAttribute), nhưng tôi không thể tìm thấy nơi để làm điều này. Tôi đã đặt chúng ở tất cả các phương pháp mà không cần giải quyết vấn đề.

Bất kỳ ý tưởng hay ý tưởng nào?

+0

+1 cho tất cả chi tiết – Oded

+0

Nó không thể hiểu được. Giải thích cách "methodCall" có thể ảnh hưởng đến msg.MethodBase. –

+0

methodCall chỉ là một chuỗi có chứa một số đại diện gần mã của cuộc gọi. Nó sẽ bằng "ICommentRepository.GetById (new Guid (\" ... \ "))" và có nghĩa là để làm cho nó dễ dàng hơn gỡ lỗi nếu bạn có thể nhìn thấy phương pháp được gọi là và các đối số truyền cho nó. Thông tin này được trích xuất bằng cách sử dụng sự phản chiếu trên msg.MethodBase và msg.InArgs. ReflectionHelper.GetMethodCall không thay đổi bất cứ điều gì trong thông điệp được truyền vào nó. – sisve

Trả lời

1

Sự khác biệt có thể là do bản dựng Gỡ lỗi và Bản phát hành không? Dưới đây là một số read tốt về lý do tại sao điều này hiển thị trong Bản dựng bản phát hành và here là các công tắc tối ưu hóa khác nhau có sẵn cho bạn. Âm thanh như một lời giải thích hợp lý, đặc biệt nếu vấn đề không liên quan đến những thay đổi gần đây.

+0

Tôi đã có '__Canon' xuất hiện trong bản dựng Gỡ lỗi. –

Các vấn đề liên quan