2012-10-19 19 views
9

Tôi đang cố gắng đăng nhập một cách không đồng bộ một số thông tin vào SQL Server bên trong một hành động điều khiển MVC 4 nhắm mục tiêu .NET 4.0 bằng cách sử dụng AsyncTargetingPack. Tôi sẽ nhảy thẳng vào NET 4.5 nhưng ứng dụng của tôi sống ở Azure và we're still waiting for the update ...Ghi nhật ký không đồng bộ ném NullReferenceException

Mã này hoạt động như mong đợi (liên tiếp được ghi vào cơ sở dữ liệu của tôi không có ngoại lệ ném):

public class SystemActionLogger : ISystemActionLogger 
{ 
    private readonly ActionBlock<Tuple<SystemAction, object>> actionBlock; 

    public SystemActionLogger(ISystemActionLogEntryRepository repository) 
    { 
     actionBlock = new ActionBlock<Tuple<SystemAction, object>>(
      entry => TaskEx.Run(async() => 
       { 
        string data = await JsonConvert.SerializeObjectAsync(entry.Item2); 
        await repository.PersistAsync(new SystemActionLogEntry(entry.Item1, data)); 
       })); 
    } 

    public void Log(SystemAction systemAction, object data) 
    { 
     actionBlock.Post(new Tuple<SystemAction, object>(systemAction, data)); 
    } 
} 

Và mã này ném một NullReferenceException:

public class SystemActionLogger : ISystemActionLogger 
{ 
    private readonly ActionBlock<Tuple<SystemAction, object>> actionBlock; 

    public SystemActionLogger(ISystemActionLogEntryRepository repository) 
    { 
     actionBlock = new ActionBlock<Tuple<SystemAction, object>>(async entry => 
      { 
       string data = await JsonConvert.SerializeObjectAsync(entry.Item2); 
       await repository.PersistAsync(new SystemActionLogEntry(entry.Item1, data)); 
      }); 
    } 

    public void Log(SystemAction systemAction, object data) 
    { 
     actionBlock.Post(new Tuple<SystemAction, object>(systemAction, data)); 
    } 
} 

NullReferenceException: "Đối tượng tham chiếu không được đặt để một thể hiện của một đối tượng"

Server stack trace: 
    at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext) 
    at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext) 
    at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state) 
    at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state) 
    at System.Runtime.CompilerServices.TaskAwaiter.<>c__DisplayClassa.<OnCompletedInternal>b__0(Task param0) 

Exception rethrown at [0]: 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 
    at System.Threading.ThreadPoolWorkQueue.Dispatch() 

Tôi không có khả năng hiển thị ngoại lệ vì đó là tất cả mã bên ngoài. Tôi không hiểu tại sao khối thứ hai của mã không thành công. Đây là mã tôi viết ban đầu.

Tôi đang làm gì sai?

+0

ASP.NET không cần hỗ trợ đặc biệt cho 'async', được thêm vào .NET 4.5. Tôi sẽ không thử sử dụng gói nhắm mục tiêu Async trên các ứng dụng ASP.NET cho .NET 4.0 - một vài điều đơn giản sẽ làm việc nhưng đường dẫn ASP.NET không sẵn sàng để xem mã 'async'. –

+1

Dấu vết ngăn xếp của bạn bao gồm tham chiếu đến 'LegacyAspNetSynchronizationContext', một loại được thêm vào trong .NET 4.5. Bạn đã cài đặt .NET 4.5 trên máy chủ Azure của bạn chưa? –

+0

Xin chào Stephen, cảm ơn vì đã trả lời. Tôi đã nhìn thấy một phản ứng tương tự từ bạn trên một bài SO khác và đã hy vọng rằng đây không phải là trường hợp, đặc biệt là kể từ khi khối đầu tiên của mã hoạt động. Về loại, tôi có. NET 4.5 được cài đặt trên hộp của tôi nhưng tôi đã không cố gắng để nhảy qua hoops và làm cho nó một phần của gói triển khai của tôi Azure. Đó là một quan sát thú vị. –

Trả lời

0

Dataflow chỉ hoạt động trên .NET 4.5. Thực tế là bạn đang chạy nó trên .NET 4.0 không được hỗ trợ và có thể là lý do tại sao bạn thấy các ngoại lệ giả mạo.

5

Tôi vừa gặp sự cố rất giống nhau (NullReference từ AssociateWithCurrentThread khi sử dụng tác vụ ghi nhật ký).

Vấn đề tôi gặp phải là hành động ban đầu không chờ hoàn thành nhiệm vụ ghi nhật ký, vì vậy khi nhật ký kết thúc và cố gắng tham gia lại chuỗi ban đầu, nullReference bị ném vì chuỗi ban đầu đã chấm dứt.

Điều này đã được giải quyết cho tôi bằng cách đảm bảo rằng bộ điều khiển yêu cầu đang chờ chức năng ghi nhật ký.

-2

Tôi gặp sự cố này với .net4.5 khi dịch vụ web của tôi đang gọi một dịch vụ WCF khác theo cách không đồng bộ. Tôi chỉ cần gắn thêm một thời gian ngắn Wait() vì tôi không quan tâm đến phản hồi (sự kiện đo từ xa).

public static void Event(string key, string message) { 
    Telemetry.Event(key, message).Wait(100); 
} 
Các vấn đề liên quan