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;
}
BTW在iPhone模擬器上運行時不會引發異常,僅在iPhone設備上失敗 –
這是AOT限制,AOT編譯器僅用於設備(因此您不會在使用JIT編譯器)。見:http://docs.xamarin.com/ios/about/limitations – poupou
*據我所知,編譯器可以忽略掉的方法,如果它認爲沒有使用它們* - > **的管理鏈接**(未編譯)可以刪除未使用的代碼,並且有方法可以防止這種情況(例如'[Preserve]'屬性)。 OTOH缺少的方法不會拋出'ExecutionEngineException'。 – poupou