I'm writing a background audio agent that plays music from an online stream and also periodically checks for updates in the track name and artist. I'm attempting to use an HttpWebRequest object to get the name and artist, but whenever I call HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result); the error below is thrown.
A first chance exception of type 'System.Net.WebException' occurred in System.Windows.dll
The stack trace for the WebException is the following:
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at AudioPlaybackAgent.AudioPlayer.TrackCallback(IAsyncResult result)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2)
at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
Digging further into the trackRequest object, I find this:
ResponseStatusCode = 'trackRequest.ResponseStatusCode' threw an exception of type 'System.NullReferenceException'
and further into that, I find this:
at System.Net.HttpWebRequest.get_ResponseStatusCode()
at AudioPlaybackAgent.AudioPlayer.TrackCallback(IAsyncResult result)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2)
at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
Here is the code I am using. The TrackTimerTick function is called every 20 seconds by a Timer.
public static void TrackTimerTick(object state) {
try {
if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing) {
// Create a HttpWebrequest object to the desired URL.
HttpWebRequest trackRequest = (HttpWebRequest)HttpWebRequest.Create("<track/artist url");
// Start the asynchronous request.
IAsyncResult result = (IAsyncResult)trackRequest.BeginGetResponse(new AsyncCallback(TrackCallback), trackRequest);
}
} catch (WebException e) {
Debug.WriteLine(e.Message);
} catch (Exception e) {
Debug.WriteLine(e.Message);
}
}
public static void TrackCallback(IAsyncResult result) {
// State of request is asynchronous.
HttpWebRequest trackRequest = (HttpWebRequest)result.AsyncState;
HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result); // WebException thrown here
using (StreamReader httpwebStreamReader = new StreamReader(trackResponse.GetResponseStream())) {
string results = httpwebStreamReader.ReadToEnd();
XDocument trackXml = XDocument.Load(results);
string title = (from t in trackXml.Descendants("channel") select t.Element("title").Value).First<string>();
string artist = (from t in trackXml.Descendants("channel") select t.Element("artist").Value).First<string>();
if (BackgroundAudioPlayer.Instance.Track != null) {
AudioTrack track = BackgroundAudioPlayer.Instance.Track;
track.BeginEdit();
track.Title = title;
track.Artist = artist;
track.EndEdit();
}
}
trackResponse.Close();
}
Can anyone help me fix this problem? Thank you in advance.
The problem is that you call NotifyComplete() before the response is arrive. I don't understand fully what happens, but you initiate the request, you call NotifyComplete, the OS froze the agent's process, then the next time the agent wakes up the WebClient immediately throws an exception, probably by design.
So the solution is to don't call NotifyComplete until you got the response.
In my case I had to look at my project error log where normally exceptions are thrown and it was printing the message Unable to create an SSL/TLS secure channel. in System.Net.HttpWebRequest.GetResponse() and to solve this I added ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; before my request, but you can put it to be executed on your starter method or class. I think other think that you can do is to add the response in try and catch exception
try
{
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Response response = new JavaScriptSerializer().Deserialize<Response>(result);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
And here your response class
public class Response
{
public string value_02 { get; set; }
public string value_03 { get; set; }
public string value_04 { get; set; }
public string value_05 { get; set; }
public string value_05 { get; set; }
}
Fact that for me gave the exception
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.ObjectDisposedException' in System.dll
Exception thrown: 'System.Net.WebException' in System.dll
Exception thrown: 'System.Net.WebException' in System.dll
Exception thrown: 'System.NullReferenceException'
And I have added to solve my problem
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
Solved my problem
Related
I am trying to execute a PowerShell script with C# with the System.Management.Automation.Powershell object in a kiosk environment, but I am always getting an exception and I have found nothing about this on the internet.
Here is my Exception:
The type initializer for 'System.Management.Automation.ExperimentalFeature' threw an exception.
Exception:
System.TypeInitializationException: The type initializer for 'System.Management.Automation.ExperimentalFeature' threw an exception.
---> System.TypeInitializationException: The type initializer for 'System.Management.Automation.Configuration.PowerShellConfig' threw an exception.
---> System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.IO.Path.Combine(String path1, String path2)
at System.Management.Automation.Configuration.PowerShellConfig..ctor()
at System.Management.Automation.Configuration.PowerShellConfig..cctor()
--- End of inner exception stack trace ---
at System.Management.Automation.ExperimentalFeature..cctor()
--- End of inner exception stack trace ---
at System.Management.Automation.Runspaces.AsyncResult.EndInvoke()
at System.Management.Automation.PowerShell.EndInvoke(IAsyncResult asyncResult)
at ExamX_Service.WindowsService.PowershellHandler.executeCommand(String command) in F:\Programmieren\ExamX_Service\ExamX_Service\PowershellHandler.cs:line 31
at ExamX_Service.WindowsService.WindowsBackgroundService.RunRecoveryScript() in F:\Programmieren\ExamX_Service\ExamX_Service\WindowsBackgroundService.cs:line 111
at ExamX_Service.WindowsService.WindowsBackgroundService.ExecuteAsync(CancellationToken stoppingToken) in F:\Programmieren\ExamX_Service\ExamX_Service\WindowsBackgroundService.cs:line 73
And my code for executing the PowerShell script is:
private static PowerShell powerShell = PowerShell.Create();
public static string executeCommand(string command)
{
string errorMsg = string.Empty;
string output = string.Empty;
powerShell.AddScript(command);
powerShell.AddCommand("Out-String");
PSDataCollection<PSObject> outputCollection = new();
powerShell.Streams.Error.DataAdded += (object sender, DataAddedEventArgs e) =>
{
errorMsg = ((PSDataCollection<ErrorRecord>)sender)[e.Index].ToString();
};
IAsyncResult result = powerShell.BeginInvoke<PSObject, PSObject>(null, outputCollection);
powerShell.EndInvoke(result);
StringBuilder sb = new();
foreach (var outputitem in outputCollection)
{
sb.AppendLine(outputitem.BaseObject.ToString());
}
powerShell.Commands.Clear();
if (!string.IsNullOrEmpty(errorMsg))
{
return errorMsg;
}
return sb.ToString().Trim();
}
Any help or knowledge sharing is much appreciated.
In the following code:
[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;
}
When I execute this code, my debug output shows:
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).
I am not understanding how my write lock is unlocking partway through the code, with the only write unlock line I have being at the end in a finally block.
Can anyone shed some light on this for me, and/or suggest a better approach?
I am dealing with an OAuth system that has an access token that must be refreshed every hour (when I am finally done with it). I have implemented this Refresh method to accomplish the goal, and use a Task.Delay().ContinueWith() call to schedule the refresh to run automatically. I am using a ReadWriterLockSlim so that I can lock the reads from continuing while the refresh is happening. Otherwise I want them to work normally. I need them locked because once I request the new token from the server on the refresh, I can no longer use the old auth token.
Aleks Andreev, thank you.
So the solution is to not use ReadWriterLockSlim, but rather to install the Nito.AsyncEx NuGet module and then use the AsyncReadWriterLock from it. Because ReadWriterLockSlim does not work with async/await.
I have a web service that should pull about 80 records from SQL database. However recently it started giving me out of memory error.
When I debug it - it shows me the web service on the list, once I run it - get the error below.
webmethod:
[WebMethod(Description = "Getting Weekly Events by Facility, future events from sunday", CacheDuration = 600)]
public List<EventViewModel> GetWeeklyEvents(string facilityNumber, DateTime StDate)
{
var db = new DS_AIMDataContext();
var eventList = from evt in db.GetPublishedEventsFromSundayByFacility(facilityNumber, StDate)
select new EventViewModel
{
EventName = evt.ActName,
EventNameSpanish = evt.ActNameSp,
EventDescription = evt.ActDescription,
EventDescrSpanish = evt.ActDescrSp,
StDate = evt.EventStart.Value,
EndDate = evt.EventEnd.Value,
EventCategory = evt.CategoryName,
EventCatID = evt.ActCategID.Value,
EventType = evt.ActType,
EventLocation = evt.LocName,
EventLeader = evt.LeaderName,
EventCategorySp = evt.CategoryNameSp,
EventTypeSp = evt.ActTypeSp,
EventRecurrenceRule = evt.RecurrenceRule,
EventPhoto1 = evt.Photo1 == null ? null : evt.Photo1.ToArray(),
EventPhoto2 = evt.Photo2 == null ? null : evt.Photo2.ToArray(),
EventPhoto3 = evt.Photo3 == null ? null : evt.Photo3.ToArray()
};
return eventList.ToList();
}
The function itself:
public IEnumerable<tblEventsWithRecurr> GetPublishedEventsFromSundayByFacility(string facN, DateTime StDate)
{
var eventList = from evt in this.tblEventsWithRecurrs
orderby Convert.ToDateTime(evt.EventStart.ToString()).Day, Convert.ToDateTime(evt.EventStart.ToString()).Hour, Convert.ToDateTime(evt.EventStart.ToString()).Minute
where (evt.FacN == facN && evt.EventStatus == "Final" && evt.EventStart >= StDate && evt.EventStart <= StDate.AddDays(31))
select evt;
return eventList;
}
Error that I'm getting is below:
Server Error in '/' Application.
Exception of type 'System.OutOfMemoryException' was thrown.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
System.IO.MemoryStream.set_Capacity(Int32 value) +93
System.IO.MemoryStream.EnsureCapacity(Int32 value) +90
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +326
Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter.Write(Byte[] buffer, Int32 offset, Int32 count) +61
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +9641608
System.Web.HttpResponse.FilterOutput() +104
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +58
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
Couple of things:
First, how big are your Photo files - you have 3 photo's you're sending back. It would not be difficult to imagine a dozen very large photos on all of your results to max out whatever memory you have going on.
Secondly:
You may want to consider disposing of your datacontext.
Currently you have:
var db = new DS_AIMDataContext();
And this is never explicitly disposed, meaning the GC will eventually get to it, where you could instruct it to be disposed of the moment you are finished with it.
So try that line to:
using (DS_AIMDataContext db = new DS_AIMDataContext()){
// all of your eventList projection
// and your return statement
}
This will call Dispose as soon as your method completes and will hopefully free up memory.
public async static Task<WebResponse> GetResponseAsync(this HttpWebRequest request, Dictionary<string, object> post)
{
var tcs = new TaskCompletionSource<WebResponse>();
try
{
request.BeginGetRequestStream((arReq) =>
{
var stream = request.EndGetRequestStream(arReq);//throw NotSupportedException
writeMultipartObject(stream, post);
stream.Close();
request.BeginGetResponse((ar) =>
{
var response = request.EndGetResponse(ar);
tcs.SetResult(response);
}, null);
}, null);
}
catch (Exception we)
{
tcs.SetException(we);
}
return await tcs.Task;
}
when i post something, it no works..=.=
var stream = request.EndGetRequestStream(arReq);//throw NotSupportedException
tell me why? ToT.................
System.NotSupportedException ---> System.NotSupportedException: Specified method is not supported.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c_DisplayClasse.b_d(Object sendState)
at System.Net.Browser.AsyncHelper.<>c_DisplayClass1.b_0(Object sendState)
I have experienced similar behaviour (on Windows Phone only) and got it working by explicitly disposing the stream you're writing to.
So try to add
stream.Flush();
before, and
stream.Dispose();
after your
stream.Close();
statement and see if that helps.
Apparently, the behaviour of the networking stack in .Net is different dependent on the platform your code runs on, due to the fact that the .Net framework is "redeveloped" for each platform.
I hope this helps.
Cheers,
Kristof.
Sometimes I'm getting an exception when trying to get the position of the BackgroundAudioPlayer.Instance. It's happening very rarely, but I've been able to get a StackTrace. The strange thing is, this code is executed every second while playing a track. What could be the cause of this error?
I'm getting this StackTrace.
System.SystemException: HRESULT = 0xC00D36C4 ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0xC00D36C4 at
Microsoft.Phone.BackgroundAudio.Interop.IAudioPlaybackManager.get_CurrentPosition() at
Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer.get_Position() --- End of inner exception stack trace --- at
Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer.get_Position() at
MC.PodCast.Common.ViewModel.PlayerViewModel.UpdateTrackPosition() at
MC.PodCast.Common.ViewModel.PlayerViewModel.ReactToBackgroundAudioPlayer() at
MC.PodCast.Common.ViewModel.PlayerViewModel.Initialize() at
MC.PodCast.Common.ViewModel.PlayerViewModel.<<get_InitializeCommand>b__5>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__0(Object state)
Of course the code I'm using is just plain simple.
public void UpdateTrackPosition()
{
if (_backgroundAudioPlayer != null && _backgroundAudioPlayer.Track != null)
{
Position = _backgroundAudioPlayer.Position;
}
else
{
Position = null;
}
}
That code is linked to MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED but I'm guessing that you do have sound.
I have found that the BackgroundAudioPlyer can be very weird. I wrap most of my calls with a "Safe" extension method.
Example
public static PlayState PlayerStateSafe(this BackgroundAudioPlayer source)
{
PlayState state;
try
{
state = source.PlayerState;
}
catch (InvalidOperationException)
{
state = PlayState.Unknown;
}
return state;
}