C#读写器锁定解锁?

C#读写器锁定解锁?,c#,oauth,async-await,C#,Oauth,Async Await,在以下代码中: [System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS4014:Await.Warning")] private async Task<bool> Refresh() { log.Info("Refreshing Token."); Debug.WriteLine("Refreshing Token.");

在以下代码中:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS4014:Await.Warning")]
        private async Task<bool> Refresh()
        {
            log.Info("Refreshing Token.");
            Debug.WriteLine("Refreshing Token.");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_URL);
            request.Method = "POST";
            request.ContentType = "application/json; charset=UTF-8";
            request.Headers.Add("Authorization", "basic " + authCode);
            request.Accept = "application/json, text/javascript, */*; q=0.01";
            request.ContentLength = payload.Length;

            log.Debug(request.Headers["Authorization"]);
            Debug.WriteLine(request.Headers["Authorization"]);

            using (Stream writeStream = request.GetRequestStream())
            {
                await writeStream.WriteAsync(payload, 0, payload.Length);
            }

            lock (tokenLock)
            {
                Debug.WriteLine($"Write Lock enabled? {tokenLock.IsWriteLockHeld}");
                tokenLock.EnterWriteLock();
                Debug.WriteLine($"Write Lock enabled? {tokenLock.IsWriteLockHeld}");
            }
            try
            {
                string body;
                using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
                {
                    int numericStatusCode = (int)response.StatusCode;
                    Debug.WriteLine($"Response Code: {numericStatusCode}");
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        log.Error($"!!!!! Request failed. Received HTTP {response.StatusCode}");
                        body = string.Empty;
                    }
                    else
                    {
                        string responseValue = string.Empty;
                        using (Stream responseStream = response.GetResponseStream())
                        {
                            if (responseStream != null)
                            {
                                using (StreamReader reader = new StreamReader(responseStream))
                                {
                                    responseValue = await reader.ReadToEndAsync();
                                }
                            }
                        }
                        body = responseValue;

                        Debug.WriteLine($"Response Body = {body}");
                        log.Trace($"Response Body = {body}");
                    }
                }
                Debug.WriteLine($"Write Lock enabled? {tokenLock.IsWriteLockHeld}");
                if (!string.IsNullOrEmpty(body))
                {
                    _token = JsonConvert.DeserializeObject<AuthTokenInfo>(body, serializerSettings);

                    refreshUri = _token.RefreshTokenServerUri;
                    payload = Encoding.GetEncoding("utf-8").GetBytes(
                        JsonConvert.SerializeObject(new { grant_type = "refresh_token", _token.RefreshToken })
                    );
                    Debug.WriteLine($"Write Lock enabled? {tokenLock.IsWriteLockHeld}");
                    Debug.WriteLine($"Token Refreshed, Expires In = {_token.ExpiresIn}");
                    Debug.WriteLine($"Access Token = {_token.AccessToken}");

                    Debug.WriteLine($"New Token Refresh URI: {refreshUri}");
                    Debug.WriteLine($"New Refresh Token: {_token.RefreshToken}");
                    if (_token != null)
                    {
                        int refreshTime = 60 * 1000; // (Token.ExpiresIn.Value - (15 * 60)) * 1000;
                        log.Info($"Refreshing token in {refreshTime} milliseconds.");
                        Debug.WriteLine($"Refreshing token in {refreshTime} milliseconds.");

                        Task.Delay(refreshTime).ContinueWith(async (action) =>
                        {
                            log.Info("Refreshing token NOW.");
                            Debug.WriteLine("Refreshing token NOW.");
                            await Refresh();
                        });

                        Debug.WriteLine("Refresh scheduled.");
                    }
                }
            }
            finally
            {
                lock(tokenLock)
                {
                    Debug.WriteLine($"Write Lock enabled? {tokenLock.IsWriteLockHeld}");
                    tokenLock.ExitWriteLock();
                    Debug.WriteLine($"Write Lock enabled? {tokenLock.IsWriteLockHeld}");
                }
            }
            return true;
        }
[System.Diagnostics.CodeAnalysis.SuppressMessage(“wait.Warning”,“CS4014:wait.Warning”)]
专用异步任务刷新()
{
log.Info(“刷新令牌”);
Debug.WriteLine(“刷新令牌”);
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(令牌\ URL);
request.Method=“POST”;
request.ContentType=“application/json;charset=UTF-8”;
添加(“授权”、“基本”+authCode);
request.Accept=“application/json,text/javascript,*/*;q=0.01”;
request.ContentLength=有效负载.Length;
log.Debug(request.Headers[“Authorization”]);
Debug.WriteLine(request.Headers[“Authorization”]);
使用(Stream writeStream=request.GetRequestStream())
{
wait writeStream.WriteAsync(有效载荷,0,有效载荷.Length);
}
锁(令牌锁)
{
Debug.WriteLine($“已启用写锁?{tokenLock.iswritelockhold}”);
tokenLock.EnterWriteLock();
Debug.WriteLine($“已启用写锁?{tokenLock.iswritelockhold}”);
}
尝试
{
弦体;
使用(HttpWebResponse=(HttpWebResponse)wait request.GetResponseAsync())
{
int numericStatusCode=(int)response.StatusCode;
WriteLine($“响应代码:{numericStatusCode}”);
if(response.StatusCode!=HttpStatusCode.OK)
{
log.Error($“!!!!!请求失败。收到HTTP{response.StatusCode}”);
body=string.Empty;
}
其他的
{
string responseValue=string.Empty;
使用(Stream responseStream=response.GetResponseStream())
{
if(responseStream!=null)
{
使用(StreamReader=新StreamReader(responseStream))
{
responseValue=wait reader.ReadToEndAsync();
}
}
}
主体=响应值;
WriteLine($“响应体={Body}”);
Trace($“Response Body={Body}”);
}
}
Debug.WriteLine($“已启用写锁?{tokenLock.iswritelockhold}”);
如果(!string.IsNullOrEmpty(body))
{
_token=JsonConvert.DeserializeObject(主体,SerializeSettings);
refreshUri=\u token.RefreshTokenServerUri;
有效负载=Encoding.GetEncoding(“utf-8”).GetBytes(
SerializeObject(新的{grant_type=“refresh_token”,_token.refreshttoken})
);
Debug.WriteLine($“已启用写锁?{tokenLock.iswritelockhold}”);
Debug.WriteLine($”令牌刷新,过期时间={u Token.ExpiresIn}”);
Debug.WriteLine($“访问令牌={u-Token.AccessToken}”);
WriteLine($“新令牌刷新URI:{refreshUri}”);
WriteLine($“新刷新令牌:{u-Token.refreshttoken}”);
如果(_标记!=null)
{
int refreshTime=60*1000;//(Token.ExpiresIn.Value-(15*60))*1000;
Info($“在{refreshTime}毫秒内刷新令牌。”);
WriteLine($“刷新令牌的时间为{refreshTime}毫秒。”);
Task.Delay(refreshTime).ContinueWith(异步(操作)=>
{
log.Info(“立即刷新令牌”);
WriteLine(“立即刷新令牌”);
等待刷新();
});
WriteLine(“刷新计划”);
}
}
}
最后
{
锁(令牌锁)
{
Debug.WriteLine($“已启用写锁?{tokenLock.iswritelockhold}”);
ExitWriteLock();
Debug.WriteLine($“已启用写锁?{tokenLock.iswritelockhold}”);
}
}
返回true;
}
执行此代码时,调试输出显示:

Refreshing Token.
Write Lock enabled? False
Write Lock enabled? True
Response Code: 200
Write Lock enabled? False
Write Lock enabled? False
Token Refreshed, Expires In = 3600
Refreshing token in 60000 milliseconds.
Refresh scheduled.
Write Lock enabled? False
Exception thrown: 'System.Threading.SynchronizationLockException' in System.Core.dll
Exception thrown: 'System.AggregateException' in mscorlib.dll
Exception thrown: 'System.TypeInitializationException' in InContactApi.dll
Exception thrown: 'System.TypeInitializationException' in mscorlib.dll
Exception thrown: 'System.AggregateException' in mscorlib.dll
An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll
One or more errors occurred.


Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.TypeInitializationException: The type initializer for 'InContact.Auth' threw an exception. ---> System.AggregateException: One or more errors occurred. ---> System.Threading.SynchronizationLockException: The write lock is being released without being held.
   at System.Threading.ReaderWriterLockSlim.ExitWriteLock()
   at InContact.AuthToken.<Refresh>d__12.MoveNext() in C:\Users\chill\source\repos\interactive_intelligence\InContactApi\InContactApi\Auth.cs:line 206
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at InContact.AuthToken..ctor() in C:\Users\chill\source\repos\interactive_intelligence\InContactApi\InContactApi\Auth.cs:line 106
   at InContact.Auth..cctor() in C:\Users\chill\source\repos\interactive_intelligence\InContactApi\InContactApi\Auth.cs:line 236
   --- End of inner exception stack trace ---
   at InContact.Auth.get_BaseURL()
   at InContact.InContactApi.MakeRequestURL(String subURL, Dictionary`2 query, String callerName) in C:\Users\chill\source\repos\interactive_intelligence\InContactApi\InContactApi\InContactApi.cs:line 127
   at InContact.InContactApi.<GetFolderListing>d__26.MoveNext() in C:\Users\chill\source\repos\interactive_intelligence\InContactApi\InContactApi\InContactApi.cs:line 607
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at CallLogger.ICRecordings.<DirTraverse>d__8.MoveNext() in C:\Users\chill\source\repos\interactive_intelligence\CallLogger\CallLogger\ICRecordings.cs:line 73
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at CallLogger.Program.Main() in C:\Users\chill\source\repos\interactive_intelligence\CallLogger\CallLogger\Program.cs:line 32
The program '[34036] PhoneLogger.exe' has exited with code 0 (0x0).
刷新令牌。
是否启用写锁?假的
是否启用写锁?真的
响应代码:200
是否启用写锁?假的
是否启用写锁?假的
令牌已刷新,过期时间=3600
在60000毫秒内刷新令牌。
已计划刷新。
是否启用写锁?假的
引发异常:System.Core.dll中的“System.Threading.SynchronizationLockException”
引发异常:mscorlib.dll中的“System.AggregateException”
引发异常:InContactApi.dll中的“System.TypeInitializationException”
引发异常:mscorlib.dll中的“System.TypeInitializationException”
引发异常:mscorlib.dll中的“System.AggregateException”
mscorlib.dll中发生类型为“System.AggregateException”的未处理异常
发生了一个或多个错误。
未处理的异常:System.AggregateException:发生一个或多个错误。-->System.TypeInitializationException:“InContact.Auth”的类型初始值设定项引发异常。-->System.AggregateException:发生一个或多个错误。-->System.Threading.SynchronizationLockException:正在释放写入锁而未保持。
在System.Threading.ReaderWriterLockSlim.ExitWriteLock()中
在C:\Users\chill\source\repos\intera中的InContact.AuthToken.d\uuu 12.MoveNext()处