2012-12-04 21 views
4

據我所知,編譯器可以忽略掉的方法,如果它認爲沒有使用它們,就可以解決這個直接在代碼中引用的方法強制編譯器包含它。但是,在這種情況下,它似乎不起作用。System.ExecutionEngineException:試圖JIT編譯方法System.Threading.Interlocked:交易所

這裏的例外,調用堆棧:

System.ExecutionEngineException: Attempting to JIT compile method '(wrapper managed-to-native) System.Threading.Interlocked:Exchange (System.Threading.Tasks.IContinuation&,System.Threading.Tasks.IContinuation)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information. 

at System.Threading.Tasks.TaskCompletionQueue`1[System.Threading.Tasks.IContinuation].TryGetNextCompletion (IContinuation& continuation) [0x00000] in <filename unknown>:0 
at System.Threading.Tasks.Task.ProcessCompleteDelegates() [0x0001b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:521 
at System.Threading.Tasks.Task.HandleGenericException (System.AggregateException e) [0x0001a] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:563 
at System.Threading.Tasks.Task.TrySetException (System.AggregateException aggregate) [0x0003e] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:440 
at System.Threading.Tasks.TaskCompletionSource`1[System.Net.WebResponse].TrySetException (IEnumerable`1 exceptions) [0x00000] in <filename unknown>:0 
at System.Threading.Tasks.TaskCompletionSource`1[System.Net.WebResponse].SetException (IEnumerable`1 exceptions) [0x00000] in <filename unknown>:0 
at System.Threading.Tasks.TaskCompletionSource`1[System.Net.WebResponse].SetException (System.Exception exception) [0x00000] in <filename unknown>:0 
at System.Threading.Tasks.TaskFactory`1[System.Net.WebResponse].InnerInvoke (System.Threading.Tasks.TaskCompletionSource`1 tcs, System.Func`2 endMethod, IAsyncResult l) [0x00000] in <filename unknown>:0 
at System.Threading.Tasks.TaskFactory`1+<FromAsyncBeginEnd>c__AnonStorey21[System.Net.WebResponse].<>m__15 (IAsyncResult l) [0x00000] in <filename unknown>:0 
at Vistian.Net.Http.HttpRequestProcessor+<BeginGetResponse>c__AnonStorey3.<>m__5 (IAsyncResult result) [0x00082] in /Users/martinstafford/Projects/Vistian/vistian/common/Vistian.Net/trunk/Vistian.Net.Portable/Http/HttpRequestProcessor.cs:441 
at System.Net.WebAsyncResult.CB (System.Object unused) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebAsyncResult.cs:148 

我試過,包括這條線在構造函數的類與它的問題,但仍然出現錯誤:

object dummy = System.Threading.Interlocked.Exchange(ref dummyLock, new object()); 

這裏的錯誤周圍的代碼。對不起,有這麼多,但它在上下文中。調用「回調」時會引發異常 - 任何一種。正如你所看到的,我想實現一類異步編程模型,它包括GetRequestStream和GetResponse的兩個異步操作:

    public static IAsyncResult BeginGetResponse(AsyncCallback callback, object state) 
    { 
     var requestProcessor = state as HttpRequestProcessor; 

     // create the Uri of the Host and Path in the request 
     // and use it to create a HttpWebRequest 
     Uri u = new Uri(new Uri(requestProcessor.Request.Host), requestProcessor.Request.Path); 
     requestProcessor.HttpWebRequest = WebRequest.Create(u) as HttpWebRequest; 

     // set up the header of the HttpWebRequest 
     requestProcessor.SetupHeader(requestProcessor.HttpWebRequest, requestProcessor.Request); 

     requestProcessor.WebResponse = null; 
     requestProcessor.RaisedException = null; 

     // set up an event to be used to 'timeout' the forthcoming async process 
     var syncRef = new System.Threading.AutoResetEvent(false); 

     System.Diagnostics.Debug.WriteLine(string.Format("HttpRequestProcessor.BeginGetResponse: started method={0}", requestProcessor.Request.Method)); 

     // perform the request using the Async method 
     // GET and POST requests are processed differently 
     if (requestProcessor.Request.Method == HttpMethod.POST) 
     { 
      // create the request content using the serialiser 
      var bytes = requestProcessor.Encoder.Encode(requestProcessor.Request.Data, requestProcessor.Request.ContentType); 

      System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: BeginGetRequestStream started"); 

      // start the async process by adding the content to the request 
      requestProcessor.HttpWebRequest.BeginGetRequestStream((IAsyncResult result) => 
      { 
       // the asyncronous Get RequestStream has finished in some way 
       // complete the Get RequestStream process by calling EndGetRequestStream 

       // get the HttpWebRequest provided in the 'state' parameter and 
       // use it to call EndGetRequestStream 
       var request = result.AsyncState as HttpWebRequest; 
       try 
       { 
        // fill the request stream with the content 
        using (Stream requestStream = request.EndGetRequestStream(result)) 
        { 
         requestStream.Write(bytes, 0, bytes.Length); 
        } 

        System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: EndGetRequestStream"); 
       } 
       catch (Exception e) 
       { 
        // if the filling of the request stream fails, finish the Async process here 
        System.Diagnostics.Debug.WriteLine(string.Format("HttpRequestProcessor.BeginGetResponse: EndGetRequestSteam failed. Uri={0}", request.RequestUri)); 

        // remember the exception, to be picked up by the subsequent call in to EndGetResponse 
        requestProcessor.RaisedException = e; 

        // clear the timeout event to indicate the async process has finished 
        syncRef.Set(); 

        // call the callback as the async process is finished 
        callback(new AsyncResult(requestProcessor, true)); 

        return; 
       } 

       System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: BeginGetResponse started"); 

       // the HttpWebRequest has the request content in it 
       // send the request and get the response 
       request.BeginGetResponse((IAsyncResult responseResult) => 
       { 
        // the Async process GetResponse has finished in some way 
        // get the HttpWebRequest provided as a parameter and use it 
        // to complete the GetRespone process 

        HttpWebRequest req = responseResult.AsyncState as HttpWebRequest; 
        try 
        { 
         requestProcessor.WebResponse = req.EndGetResponse(responseResult); 
         System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: EndGetResponse"); 
        } 
        catch (Exception e) 
        { 
         // if getting the response fails, catch and remember the exception 
         // for the subsequent call in to EndGetResponse 
         System.Diagnostics.Debug.WriteLine(string.Format("HttpRequestProcessor.BeginGetResponse: EndGetResponse failed. Uri={0}", req.RequestUri)); 
         requestProcessor.RaisedException = e; 
        } 

        // clear the timeout timer event 
        syncRef.Set(); 

        // call the async callback 
        callback(new AsyncResult(requestProcessor, true)); 

        System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: POST callback complete"); 

       }, request); 

      }, requestProcessor.HttpWebRequest); 
     } 
     else 
     { 
      requestProcessor.HttpWebRequest.BeginGetResponse((IAsyncResult responseResult) => 
      { 
       HttpWebRequest req = responseResult.AsyncState as HttpWebRequest; 

       try 
       { 
        requestProcessor.WebResponse = req.EndGetResponse(responseResult); 
        System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: EndGetResponse"); 
       } 
       catch (Exception e) 
       { 
        System.Diagnostics.Debug.WriteLine(string.Format("HttpRequestProcessor.BeginGetResponse: EndGetResponse failed. Uri={0}", req.RequestUri)); 
        requestProcessor.RaisedException = e; 
       } 

       syncRef.Set(); 

       callback(new AsyncResult(requestProcessor, true)); 

       System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: GET callback complete"); 

      }, requestProcessor.HttpWebRequest); 
     } 

     // wait for the async process to finish or timeout 
     if (!syncRef.WaitOne(requestProcessor.Request.Timeout)) 
     { 
      // async process has time out 
      System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.BeginGetResponse: BeginGetStreamRequest timed out"); 

      // abort the async process and create and remember an exception 
      // to be picked up by the call in the EndGetResponse 
      requestProcessor.HttpWebRequest.Abort(); 
      requestProcessor.RaisedException = new TimeoutException("loading request stream timed out"); 
     } 

     return new AsyncResult(requestProcessor, false); 
    } 

    public static WebResponse EndGetResponse(IAsyncResult result) 
    { 
     System.Diagnostics.Debug.WriteLine("HttpRequestProcessor.EndGetResponse:"); 

     var requestProcessor = result.AsyncState as HttpRequestProcessor; 

     if (requestProcessor.RaisedException != null) 
     { 
      throw requestProcessor.RaisedException; 
     } 
     return requestProcessor.WebResponse; 
    } 
+0

BTW在iPhone模擬器上運行時不會引發異常,僅在iPhone設備上失敗 –

+0

這是AOT限制,AOT編譯器僅用於設備(​​因此您不會在使用JIT編譯器)。見:http://docs.xamarin.com/ios/about/limitations – poupou

+0

*據我所知,編譯器可以忽略掉的方法,如果它認爲沒有使用它們* - > **的管理鏈接**(未編譯)可以刪除未使用的代碼,並且有方法可以防止這種情況(例如'[Preserve]'屬性)。 OTOH缺少的方法不會拋出'ExecutionEngineException'。 – poupou

回答

2

加入這構造做到了:

VAR虛擬= System.Threading.Interlocked.Exchange(ref dummyTask,System.Threading.Tasks.Task.Factory.StartNew(()=> {}));