System.Threading._IOCompletionCallback.PerformIOCompletionCallback(...)中的System.AccessViolationException

时间:2014-01-09 17:52:32

标签: c# .net multithreading

使用.Net框架4,我在多线程C#代码中获得了System.AccessViolationException,即使我的所有代码都是托管代码。这可能是.Net中的一个错误,因为我一直认为使用.Net意味着无论我做出什么编程错误,都不应该发生AccessViolationException?

我从Visual Studio 2010获得的唯一错误消息是

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

没有调用堆栈信息(它只是说[External Code]),即使我打开非托管调试以尝试查看本机调用堆栈,也是如此。

我的应用程序通过公共互联网将多个同时的http调用发送到返回JSON对象的API。所有的调用都是通过我在下面粘贴的AsyncResult类进行的。关于如何解决这个问题的任何建议都是非常受欢迎的。

public class AsyncResult<T> : IDisposable where T : class  {
    private const int NumPasses = 2;            // if Exception thrown on first pass, try again in case it was an internet problem

    public readonly System.Threading.ManualResetEvent allDone;
    public readonly string method;
    public readonly IDictionary<string, object> args;
    private readonly RpcClient.CreateWebRequestDelegate cwr_deleg;
    private readonly VoidVoidDelegate cb;                   // to be called when Async operation complete or abandoned
    public readonly string LocationDescripForError;
    private int m_count;    // number of passes.  Call should execute on first pass
    private bool m_Abort;   // mechanism for aborting from outside the object
    private int m_Stage;  // 0 = waiting for GetRequestStreamCallback, 1 = waiting for GetResponseCallback, 2 or greater = waiting for ReadStreamCallBack
    private System.Exception m_exception;  // non null if an exception has occurred
    private WebRequest request;
    private IAsyncResult iasr_GetRequestStream;
    private IAsyncResult iasr_GetResponse;
    private IAsyncResult iasr_streamRead;
    private WebResponse response;
    private Stream responseStream;

    private const int BUFFER_SIZE = 1024;
    private byte[] buffer;
    private StringBuilder sb_jsonResponse;

    private T result;

    public AsyncResult(string method, IDictionary<string, object> args, RpcClient.CreateWebRequestDelegate cwr_deleg, string LocationDescripForError, VoidVoidDelegate cb) {
        allDone = new System.Threading.ManualResetEvent(false);
        this.method = method; this.args = args; this.cwr_deleg = cwr_deleg; this.LocationDescripForError = LocationDescripForError; this.cb = cb;
        m_count = 0; m_Abort = false; buffer = new byte[BUFFER_SIZE]; sb_jsonResponse = new StringBuilder("");
        InitiateCallSequence();
    }

    ~AsyncResult() { try { Dispose(); } catch {} }

    private void InitiateCallSequence() {
        if (m_Abort) return;
        m_count++;
        m_Stage = 0; m_exception = null; sb_jsonResponse.Clear();
        request = cwr_deleg();
        iasr_GetRequestStream = (IAsyncResult)request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), null);
    }

    private void ExceptionHandling(System.Exception Ex) {
        if (m_count < NumPasses) {
            try {
                iasr_GetRequestStream = null; InitiateCallSequence();
                if (iasr_GetRequestStream != null) return;
            } catch { }
        }
        m_exception = Ex;
        lock (allDone) {
            if (!m_Abort) allDone.Set();
        }
        if (cb != null) cb();
    }

    private void GetRequestStreamCallback(IAsyncResult asynchronousResult) {
        System.Threading.Interlocked.Increment(ref m_Stage);
        try {
            using (Stream streamResponse = request.EndGetRequestStream(asynchronousResult)) {
                if (m_Abort) return;
                using (StreamWriter writer = new StreamWriter(streamResponse, Encoding.UTF8)) {
                    Request call = new Request { Method = method, Id = 1, Params = args };
                    Convert.Export(call, writer);
                }
            }
            iasr_GetResponse = (IAsyncResult)request.BeginGetResponse(new AsyncCallback(GetResponseCallback), null);
        } catch (System.Exception Ex) { ExceptionHandling(Ex); }
    }

    private void GetResponseCallback(IAsyncResult asynchronousResult) {
        System.Threading.Interlocked.Increment(ref m_Stage);
        try {
            response = request.EndGetResponse(asynchronousResult); // End the Asynchronous response.
            if (m_Abort) return;
            // Read the response into a 'Stream' object.
            responseStream = response.GetResponseStream();
            iasr_streamRead = responseStream.BeginRead(buffer, 0, BUFFER_SIZE, new AsyncCallback(ReadStreamCallBack), null);
        } catch (System.Exception Ex) { ExceptionHandling(Ex); }
    }

    private void ReadStreamCallBack(IAsyncResult asynchronousResult) {
        System.Threading.Interlocked.Increment(ref m_Stage);
        try {
            int read = responseStream.EndRead(asynchronousResult); // End the Asynchronous read.
            if (m_Abort) return;
            if (read > 0) {
                sb_jsonResponse.Append(Encoding.ASCII.GetString(buffer, 0, read));
                iasr_streamRead = responseStream.BeginRead(buffer, 0, AsyncResult<T>.BUFFER_SIZE, new AsyncCallback(ReadStreamCallBack), null);
            } else {
                Response<T> jsonResponse = Convert.Import<T>(sb_jsonResponse.ToString());
                if (jsonResponse.HasError) {
                    System.Exception Ex = ReconstituteException(jsonResponse.Error, LocationDescripForError);
                    ExceptionHandling(Ex);
                    return;
                } else {
                    result = jsonResponse.Result;
                }
                responseStream.Dispose();
                responseStream.Close();
                if (m_count > 1) System.Diagnostics.Trace.WriteLine("AsyncResult success count=" + m_count);
                lock (allDone) {
                    if (!m_Abort) allDone.Set();
                }
                if (cb != null) cb();
            }
        } catch (System.Exception Ex) { ExceptionHandling(Ex); }
    }

    public T GetResult(int millisecondsTimeout) {                
        bool waitresult = allDone.WaitOne(millisecondsTimeout);
        if (waitresult)
            return (m_exception == null ? result : null);
        else {
            Abort();
            return null;
        }
    }

    public bool IsError { get { return (m_exception != null); } }
    public string ErrorMessage { get {
        if (m_exception == null) return string.Empty;
        WebException wex = (m_exception is WebException ? (WebException)m_exception : null);
        string retval = CoreLogging.ExceptionDescription(m_exception) + " API-NG(" + method + ":" + m_Stage + "): " + m_exception.Message + (string.IsNullOrWhiteSpace(m_exception.Source) ? "" : ", Source=" + m_exception.Source) + (wex == null ? "" : ", Status=" + wex.Status);
        return retval;
    }   }
    public int GetStage() { return m_Stage; }
    public void Abort() { m_Abort = true; Dispose(); }
    public bool IsAborted { get { return m_Abort; } }
    public void Dispose() { lock (allDone) { allDone.Dispose(); } }
}

0 个答案:

没有答案