This is the obsolete function - call the function with :
string requestData = RestClient.JiraRequest(buildFilter());
Function:
public static string JiraRequest(string api)
{
string data = string.Empty;
try
{
string requestUrl = @"https://jira.xxxxx.org/rest/api/2/" + api;
string authType = "Basic";
string httpMethod = "GET";
string authHeader = Convert.ToBase64String(Encoding.ASCII.GetBytes(Config.UserName + ":" + Config.UserPassword));
_ = Encoding.UTF8.GetBytes(authHeader);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = httpMethod;
request.Headers.Add("Authorization", authType + " " + authHeader);
request.ContentType = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new ApplicationException("Exeption error: " + response.StatusCode.ToString());
}
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
data = reader.ReadToEnd();
}
}
}
}
catch (Exception ex)
{
HandleExeption.Exception(ex);
return data;
}
return data;
}
This is the new function - call the function with :
string requestData = await RestClient.JiraRequest(buildFilter());
Function:
public static async Task<string> JiraRequest(string api)
{
string data = string.Empty;
try
{
string requestUrl = @"https://jira.xxxxx.org/rest/api/2/" + api;
string authType = "Basic";
using (HttpClient client = new())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authType, Convert.ToBase64String(Encoding.ASCII.GetBytes(Config.UserName + ":" + Config.UserPassword)));
HttpResponseMessage responseMessage = await client.GetAsync(requestUrl);
if (!responseMessage.IsSuccessStatusCode)
{
throw new ApplicationException("HttClient exception: " + responseMessage.StatusCode.ToString());
}
data = await responseMessage.Content.ReadAsStringAsync();
return data;
}
}
catch (Exception ex)
{
HandleExeption.Exception(ex);
return data;
}
}
Description and history:
with the old code, I got two messages that this approach is obsolete, so I coded the new kind of HttpClient
.
With the obsolete function, it works perfectly, but with the new function, it doesn't work anymore..
Error in the new function: it crashes after calling
HttpResponseMessage responseMessage = await client.GetAsync(requestUrl);
No exception is shown, I have also tried with Debug.Writeline
, but nothing shows up either.
After calling the this, the program simply exits (crashes)....
Exception(Exception ex):
public static void Exception(Exception ex)
{
StackTrace stackTrace = new(ex, true);
#nullable enable
StackFrame? stackFrame = stackTrace.GetFrame(stackTrace.FrameCount - 1);
#nullable disable
Debug.WriteLine($"Exception message: {ex.Message ?? "No message"}");
if (stackFrame != null)
{
var method = stackFrame.GetMethod();
Debug.WriteLine($"Exception in method: {method}");
var lineNumber = stackFrame.GetFileLineNumber();
Debug.WriteLine($"Exception in line: {lineNumber}");
}
}
I doubt your program is "crashing" at that particular line of code, because you have exception handling there, which would catch any error thrown in that method.
The only notable difference between the old and the new variant, is that the new one is asynchronous. And somewhere in the callstack that leads to this particular method to be called, you probably don't properly await
the result of the asynchronous method. Ie you have something like this
public static void Main(string[] args) {
...
methodA();
}
void methodA() {
...
methodB();
}
async Task methodB() {
...
await methodC();
}
async Task<...> methodC() {
try {
HttpResponseMessage responseMessage = await client.GetAsync(requestUrl);
...
return ...
} catch (Exception ex) {
...
}
}
So when you now call methodA()
from a synchronous context, it calls methodB()
without awaiting its result. That's perfectly valid (eventhough it will generate a warning in Visual Studio), but at this point you lose your asynchronous context. This means, that methodA()
will finish before methodB()
and this will bubble up the callstack to the Main()
method, which will also reach its end before methodB()
is finished.
And when the Main
method ends, the program terminates. Regardless of whether there are still asynchronous operations pending or not.
This probably happend when you refactored JiraRequest(string api)
from being synchronous to asynchonous.
You can try to attach a debugger to your program and setting breakpoints
await client.GetAsync(requestUrl)
await client.GetAsync(requestUrl)
Main
methodI assume your code will hit breakpoints 1 and 3, but not 2. If that's the case, your program isn't crashing but terminating normally, because the callstack is empty.
To resolve that issue, make sure
async
await
ed