I have a Web service which works fine in production environment.
But sometimes (randomly) an exception is raised :
à System.Threading.Tasks.Task.ThrowIfExceptional(Boolean
includeTaskCanceledExceptions)\r\n à
System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification)\r\n à System.Threading.Tasks.Task1.get_Result()\r\n à
fctSendRequestSynchrone[T](String sRequest, enumHttpMethod eMethod,
Object oParams)\r\n à API.csRestApi.d__0`1.MoveNext()"
Here is my code :
.........
//Here is the line which raises the exception :
fctSendRequestSynchrone<string>(string.Format("logs/{0}/message", _lIdLog), cs.enumHttpMethod.POST, oLogLigne);
.........
//-------------------------------------------------------------------------------------
private T fctSendRequestSynchrone<T>(string sRequest, csRestApi.enumHttpMethod eMethod, object oParams = null)
{
Task<T> otask = SendRequest<T>(sRequest, eMethod, oParams);
return otask.Result;
}
//-------------------------------------------------------------------------------------
public async Task<T> SendRequest<T>(string sAction, enumHttpMethod eMethod, object oParams = null)
{
string sResponse = string.Empty;
T oValue;
using (var oClient = new HttpClient(new LogginHandler(_oCnx, new HttpClientHandler())))
{
oClient.DefaultRequestHeaders.Accept.Clear();
oClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string sRequest = string.Concat(_sUrlApi, "/", sAction);
if (_oToken != null)
{
oClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(_oToken["token_type"], _oToken
["access_token"]);
}
using (HttpResponseMessage oResponse = await oClient.PostAsJsonAsync(sRequest, oParams))
{
if (oResponse.IsSuccessStatusCode)
{
HttpContent content = oResponse.Content;
sResponse = await content.ReadAsStringAsync();
}
else
{
throw new RestApiException(oResponse);
}
}
}
oValue = JsonConvert.DeserializeObject<T>(sResponse);
return oValue;
}
Do you have an idea ?
Thank you very much in advance.
Eric
Roman Kalinchuk, Crowcoder : thanks for your replies.
Roman Kalinchuk :
Here is the entire stacktrace :
à System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n à System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)\r\n à System.Threading.Tasks.Task`1.get_Result()\r\n à logs.csLogWS.fctSendRequestSynchrone[T](String sRequest, enumHttpMethod eMethod, Object oParams)\r\n à logs.csLogWS.sbrErrorLigneRejet(String sMessage, String sCdRejet, Exception oException)\r\n à logs.csLogWS.ligneLogInformation(String sMessage)\r\n à Importation.Program.sbrImportUnitaire(String sCdInfImp, String sFileNameIn, String sFileStructure, String sLiProcedure, String[] args)| à Service.API.csRestApi.<SendRequest>d__0`1.MoveNext()".
I simplified it in my preceding question post.
The application is on production environment, do I have to put pdb files on production server in order to get more stacktrace ?
Crowcoder : do you mean that .Result is waiting while SendRequest is waiting too ? What would you suggest ?
Related
I'm trying to write a contract test using PactNet for the following method:
public async Task<IEnumerable<Models.RefData.Instrument> GetInstruments(string issuerCountry, string instrumentType)
{
ValidateNotNullOrWhiteSpaceParameter(issuerCountry, nameof(issuerCountry));
ValidateNotNullOrWhiteSpaceParameter(instrumentType, nameof(instrumentType)); ;
var queryString = $"instruments?issuerCountry={HttpUtility.UrlEncode(issuerCountry)}&instrumentType={HttpUtility.UrlEncode(instrumentType)}";
int pageNo = 0;
int pageSize = 20;
_logger.LogDebug($"GetInstruments Request:{queryString}");
var httpResponseMessage = await _client.GetAsync(queryString + $"&page={pageNo}&size={pageSize}");
_logger.LogDebug($"GetInstruments Response Status Code:{httpResponseMessage.StatusCode}");
switch (httpResponseMessage.StatusCode)
{
case HttpStatusCode.OK:
var content = await httpResponseMessage.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<GetInstrumentsResponse>(content);
// if there are no results, return Empty
if (result.Metadata.TotalElements == 0)
{
return Enumerable.Empty<Models.RefData.Instrument>();
}
var instruments = new List<Models.RefData.Instrument>();
instruments.AddRange(result.Embedded.Instruments);
for (pageNo = 1; pageNo < result.Metadata.TotalPages; pageNo++)
{
var innerQueryString = queryString + $"&page={pageNo}&size={pageSize}";
_logger.LogDebug($"GetInstruments Request Additional Page:{innerQueryString}");
var httpResponseMessage2 = await _client.GetAsync(innerQueryString);
if (httpResponseMessage2.StatusCode != HttpStatusCode.OK)
{
_logger.LogError($"The requested page number {pageNo} gets response error {httpResponseMessage2.StatusCode.ToString()}.");
throw new UnexpectedResponseException(httpResponseMessage.StatusCode);
}
var content2 = await httpResponseMessage2.Content.ReadAsStringAsync();
var result2 = JsonConvert.DeserializeObject<GetInstrumentsResponse>(content2);
if (result2.Embedded.Instruments != null && result2.Embedded.Instruments.Any())
{
instruments.AddRange(result2.Embedded.Instruments);
}
}
if (instruments.Count != result.Metadata.TotalElements)
{
_logger.LogWarning($"Total number of instruments is different from MetaData. MetaData states {result.Metadata.TotalElements}, however only {instruments.Count} instruments retrieved.");
}
_logger.LogDebug($"GetInstruments Result:{instruments.ToJson()}");
return instruments;
default:
throw new UnexpectedResponseException(httpResponseMessage.StatusCode);
}
}
I created the following ConsumerPactTests.cs and ConsumerPactClassFixture.cs using this as a guide.
public class ConsumerPactTests : IClassFixture<ConsumerPactClassFixture>
{
private IMockProviderService _mockProviderService;
private string _mockProviderServiceBaseUri;
public ConsumerPactTests(ConsumerPactClassFixture fixture)
{
_mockProviderService = fixture.MockProviderService;
_mockProviderService.ClearInteractions(); //NOTE: Clears any previously registered interactions before the test is run
_mockProviderServiceBaseUri = fixture.MockProviderServiceBaseUri;
}
[Fact]
public void ItHandlesInvalidDateParam()
{
// Arange
var invalidRequestMessage = "issuerCountry or instrumentType is not valid";
_mockProviderService.Given("There is data")
.UponReceiving("A invalid GET request for Date Validation with invalid date parameter")
.With(new ProviderServiceRequest
{
Method = HttpVerb.Get,
Path = "/api/v2",
Query = "issuerCountry=USA&instrumentType=foo"
})
.WillRespondWith(new ProviderServiceResponse
{
Status = 400,
Headers = new Dictionary<string, object>
{
{ "Content-Type", "application/json; charset=utf-8" }
},
Body = new
{
message = invalidRequestMessage
}
});
// Act
RefDataHttpService sut = new RefDataHttpServiceBuilder().Build();
var result = sut.GetInstruments("USA", "foo").GetAwaiter().GetResult();
var resultBodyText = result.GetEnumerator();
// Assert
Assert.NotNull(resultBodyText);
}
}
public class ConsumerPactClassFixture : IDisposable
{
public IPactBuilder PactBuilder { get; private set; }
public IMockProviderService MockProviderService { get; private set; }
public int MockServerPort { get { return 9222; } }
public string MockProviderServiceBaseUri { get { return String.Format("http://localhost:{0}", MockServerPort); } }
public ConsumerPactClassFixture()
{
var pactConfig = new PactConfig
{
SpecificationVersion = "2.0.0",
PactDir = #"..\..\..\..\..\pacts",
LogDir = #".\pact_logs"
};
PactBuilder = new PactBuilder(pactConfig);
PactBuilder.ServiceConsumer("Consumer")
.HasPactWith("Provider");
MockProviderService = PactBuilder.MockService(MockServerPort);
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// This will save the pact file once finished.
PactBuilder.Build();
}
disposedValue = true;
}
}
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
}
#endregion
}
When I run my test I get this error:
dotnet test --filter "FullyQualifiedName=Bond.Publisher.Tests.ContractTest.ConsumerPactTests.ItHandlesInvalidDateParam"
Test run for c:\Workspace\prod\test\Bond.Publisher.Tests\bin\Debug\netcoreapp3.1\Bond.Publisher.Tests.dll(.NETCoreApp,Version=v3.1)
Microsoft (R) Test Execution Command Line Tool Version 16.7.0
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:10.95] Bond.Publisher.Tests.ContractTest.ConsumerPactTests.ItHandlesInvalidDateParam [FAIL]
X Bond.Publisher.Tests.ContractTest.ConsumerPactTests.ItHandlesInvalidDateParam [4s 196ms]
Error Message:
System.Net.Http.HttpRequestException : No connection could be made because the target machine actively refused it.
---- System.Net.Sockets.SocketException : No connection could be made because the target machine actively refused it.
Stack Trace:
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Bond.Publisher.HttpMessageHandlers.UnoAuthorisationHeaderMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in c:\Workspace\usprod\src\Bond.Publisher\HttpMessageHandlers\UnoAuthorisationHeaderMessageHandler.cs:line 37
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Bond.Publisher.Services.RefDataHttpService.GetInstruments(String issuerCountry, String instrumentType) in c:\Workspace\prod\src\Bond.Publisher\Services\RefDataHttpService.cs:line 52
at Bond.Publisher.Tests.ContractTest.ConsumerPactTests.ItHandlesInvalidDateParam() in c:\Workspace\prod\test\Bond.Publisher.Tests\ContractTest\ConsumerPactTests.cs:line 52
----- Inner Stack Trace -----
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
Test Run Failed.
I suspect it may be some sort of authentication issue as UnoAuthorisationHeaderMessageHandler.cs deals with that. What have I done wrong with this?
For me the path was too long. When I moved the project to a folder closer to C:\ the test ran.
The System.Net.Sockets.SocketException : No connection could be made because the target machine actively refused it. usually happens when there is no server listening on the url you are sending.
Check if the ruby service is up and running (the test runner starts it), you should see it in Task Manager under Visual Studio
Alernatively, before you call pactBuilder.Build(), you should be able to do an HTTP request through PostMan to http://localhost:9222/instruments...
I'm trying to call LoadPickerData method to load the result in a Picker using async/await from the a ViewModel. I get the following error:
Error
System.AggregateException
Message=One or more errors occurred. (A task was canceled.)
Source=mscorlib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2027
at System.Threading.Tasks.Task`1[TResult].GetResultCore (System.Boolean waitCompletionNotification) [0x0002b] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs:496
at System.Threading.Tasks.Task`1[TResult].get_Result () [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs:466
at EmployeeApp.Helpers.ConnectivityHelper.CheckConnectivity () [0x00049] in F:\Workspace\BajaDev\MPA\_Project\EmployeeApp\Helpers\ConnectivityHelper.cs:34
at EmployeeApp.Helpers.ConnectivityHelper.get_IsConnected () [0x00000] in F:\Workspace\BajaDev\MPA\_Project\EmployeeApp\Helpers\ConnectivityHelper.cs:21
at EmployeeApp.ViewModels.BaseViewModel.get_ServiceAreaStore () [0x00000] in F:\Workspace\BajaDev\MPA\_Project\EmployeeApp\ViewModels\BaseViewModel.cs:27
at EmployeeApp.ViewModels.MailboxViewModel.GetPickerServiceArea () [0x0000f] in F:\Workspace\BajaDev\MPA\_Project\EmployeeApp\ViewModels\MailboxViewModel.cs:60
at EmployeeApp.MailboxPage.LoadPickerData () [0x0002b] in F:\Workspace\BajaDev\MPA\_Project\EmployeeApp\Views\MailBoxPage.xaml.cs:70
at EmployeeApp.MailboxPage.OnAppearing () [0x0002c] in F:\Workspace\BajaDev\MPA\_Project\EmployeeApp\Views\MailBoxPage.xaml.cs:31
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <06692e0cad5848598a0f46942a89e99f>:0
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <06692e0cad5848598a0f46942a89e99f>:0
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in <06692e0cad5848598a0f46942a89e99f>:0
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.44(intptr,intptr)
I'm trying to load the result of a GET request in a picker, but when I start the app the first time, it does not and I get the previous exception and the second time I run it I no longer get that error.
I looked for why and I was making the call of an asynchronous method in a constructor and that is bad code, I changed it to an OnAppearing () method but still that exception keeps coming out and I don't have idea the why yet
MailboxPage.xaml.cs
public MailboxPage()
{
InitializeComponent();
BindingContext = viewModel = new MailboxViewModel();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await LoadPickerData();
}
private async Task<IEnumerable<ServiceArea>> LoadPickerData()
{
var vm = new MailboxViewModel();
var servicesareas = await vm.GetPickerServiceArea();
try
{
ServiceAreaPicker.ItemsSource = servicesareas.ToList();
ServiceAreaPicker.ItemDisplayBinding = new Binding("Name");
}
catch(AggregateException ae)
{
foreach (var e in ae.Flatten().InnerExceptions)
{
Debug.WriteLine($"{e.GetType().FullName} { e.Message}");
}
}
return servicesareas;
}
MailboxViewModel.cs
public async Task<IEnumerable<ServiceArea>> GetPickerServiceArea()
{
try
{
PickerItems = await ServiceAreaStore.GetPickerItemsAsync(true);
foreach (var item in PickerItems)
Items.Add(item);
}
catch (AggregateException ae)
{
foreach (var e in ae.Flatten().InnerExceptions)
{
Debug.WriteLine($"{e.GetType().FullName} { e.Message}");
}
}
return PickerItems;
}
ServiceAreaStoreAPI.cs
public async Task<IEnumerable<ServiceArea>> GetPickerItemsAsync(bool forceRefresh = false)
{
if (forceRefresh)
{
var json = await Client.GetStringAsync($"api/servicearea");
Servicesareas = await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<ServiceArea>>(json));
try
{
var success = LocalDatabase.AddItemsAsync(Servicesareas);
if (!success.Result)
{
//Log de fallo en la insercion de datos.
}
}
catch(AggregateException ae)
{
foreach (var e in ae.Flatten().InnerExceptions)
{
Debug.WriteLine($"{e.GetType().FullName} { e.Message}");
}
}
}
return Servicesareas;
}
In your ServiceAreaStoreAPI, you don't await a task which might be causing your issue since it'll continue on and return a canceled result.
var success = LocalDatabase.AddItemsAsync(Servicesareas);
If you have used the Task.Wait() method in the method body, then adding the async keyword to the method will fix this issue. Ex:
public async Task<ActionResult> Delete(int id) { }
I'm trying to set up RavenDb 3.5 and NServiceBus 6. After I senter the saga that I have set up in my NServiceBus endpoint, I enter a handler. Once this handler is finished, I get this error:
System.FormatException: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
My code:
public static class AutoFacConfig
{
public static IContainer ConfigureAutofac()
{
var builder = new ContainerBuilder();
var resourceManagerId = new Guid("6c9abcbb-c7ca-4a67-a149-5142f633f535");
var dtcRecoveryBasePath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
var recoveryPath = Path.Combine(dtcRecoveryBasePath, "NServiceBus.RavenDB", resourceManagerId.ToString());
builder.Register(x =>
{
var store = new DocumentStore
{
ConnectionStringName = "RavenDB",
ResourceManagerId = resourceManagerId,
TransactionRecoveryStorage = new LocalDirectoryTransactionRecoveryStorage(recoveryPath)
};
store.DefaultDatabase = "MyDB";
store.Initialize();
store.Conventions.IdentityPartsSeparator = "-";
return store;
})
.As<IDocumentStore>()
.SingleInstance();
builder.Register<IFilesStore>(x =>
{
var fileStore = new FilesStore()
{
Url = "http://localhost:40000",
DefaultFileSystem = "MyFS",
}.Initialize();
return fileStore;
}).SingleInstance();
return builder.Build();
}
}
In the saga:
protected override void ConfigureHowToFindSaga(SagaPropertyMapper<FileToOrderSagaData> mapper)
{
mapper.ConfigureMapping<StartFileToOrderSagaCommand>(m => m.DataId)
.ToSaga(s => s.DataId);
}
public async Task Handle(StartFileToOrderSagaCommand message, IMessageHandlerContext context)
{
// Do Validation ValidateXmlCommand
Data.DataId = message.DataId;
await context.Send<ValidateXmlCommand>( x => { x.Filename = message.Filename; x.CustomerId = message.CustomerId; });
}
Here's the stack trace:
at System.Guid.TryParseGuidWithNoStyle(String guidString, GuidResult& result)
at System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)
at System.Guid..ctor(String g)
at Raven.Client.Converters.GuidConverter.ConvertTo(String value) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Converters\GuidConverter.cs:line 51
at Raven.Client.Document.GenerateEntityIdOnTheClient.SetPropertyOrField(Type propertyOrFieldType, Object entity, Action`1 setIdentifier, String id) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Document\GenerateEntityIdOnTheClient.cs:line 170
at Raven.Client.Document.GenerateEntityIdOnTheClient.TrySetIdentity(Object entity, String id) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Document\GenerateEntityIdOnTheClient.cs:line 143
at Raven.Client.Document.InMemoryDocumentSessionOperations.<GenerateDocumentKeyForStorageAsync>d__99.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 833
--- 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 Raven.Client.Document.InMemoryDocumentSessionOperations.<StoreAsyncInternal>d__96.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 803
Any help guys?
After removing
store.Conventions.IdentityPartsSeparator = "-";
the issue was fixed.
See HadiEskandari's comment above and this link for more info: Exception in RavenDB.SagaPersister.Save, "Guid should contain 32 digits with 4 dashes". Guid is empty in Raven
I posted another post with the same issue. There is a simple Xamarin solution on github that you can download and run here. Please do.
It seems that calling System.Net.WebClient.DownloadDataTaskAsync in DEBUG mode on my Xperia Z3 (it works just fine with an emulator) the first time throws a NullReferenceException in System.Threading.Tasks.Task.Schedule:
public async Task<String> DownloadString(String url)
{
if (UseAuth)
webclient.Headers.Set("Authorization", TokenType + " " + AccessToken);
else if (!UseAuth && webclient.Headers["Authorization"] != null)
webclient.Headers.Remove("Authorization");
String response = "";
try
{
byte[] data = await webclient.DownloadDataTaskAsync(url);
response = Encoding.UTF8.GetString(data);
}
catch (WebException e)
{
response = new StreamReader (e.Response.GetResponseStream ()).ReadToEnd ();
ErrorResponse = JsonConvert.DeserializeObject<ErrorResponse> (response, settings);
if (ErrorResponse.Error.Status == 401 && ErrorResponse.Error.Message == "The access token expired") {
Console.WriteLine ("Error: " + ErrorResponse.Error.Status + " - " + ErrorResponse.Error.Message);
}
}
return response;
}
This code solves the problem, but I think it's a dirty fix and it doesn't really address the underlying problem.
public async Task<String> DownloadString(String url)
{
if (UseAuth)
webclient.Headers.Set("Authorization", TokenType + " " + AccessToken);
else if (!UseAuth && webclient.Headers["Authorization"] != null)
webclient.Headers.Remove("Authorization");
String response = "";
var failCount = 2;
for (int i = 0; i <= failCount; i++)
{
try
{
byte[] data = await webclient.DownloadDataTaskAsync(url);
response = Encoding.UTF8.GetString(data);
}
catch (WebException e)
{
if (i == failCount)
{
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
ErrorResponse = JsonConvert.DeserializeObject<ErrorResponse>(response, settings);
if (ErrorResponse.Error.Status == 401 && ErrorResponse.Error.Message == "The access token expired")
{
Console.WriteLine ("Error: " + ErrorResponse.Error.Status + " - " + ErrorResponse.Error.Message);
}
// Break out of the loop
break;
}
}
}
return response;
}
System.NullReferenceException: Object reference not set to an instance
of an object System.Threading.Tasks.Task.Schedule (Boolean
throwException) [0x00000] in :0 at System.Threading.Tasks.Task.Start
(System.Threading.Tasks.TaskScheduler scheduler) [0x00000] in :0 at
System.Threading.Tasks.TaskFactory.StartNew[WebRequest] (System.Func1
function, CancellationToken cancellationToken, TaskCreationOptions
creationOptions, System.Threading.Tasks.TaskScheduler scheduler)
[0x00000] in :0 at
System.Threading.Tasks.TaskFactory.StartNew[WebRequest] (System.Func1
function) [0x00000] in :0 at System.Net.WebClient.SetupRequestAsync
(System.Uri address) [0x00000] in :0 at
System.Net.WebClient+c__async0.MoveNext () [0x00000] in :0 --- End of
inner exception stack trace --- at
System.Net.WebClient+c__async0.MoveNext () [0x00000] in :0 --- End of
stack trace from previous location where exception was thrown --- at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
[0x00000] in :0 at
System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]].GetResult
() [0x00000] in :0 at
SpotifyWebAPI.SpotifyWebAPIClass+c__async1A.MoveNext () [0x00133]
System.Net.WebException
Here is a screenshot from Xamarin Studio
The problem only happens with my device and DEBUG build mode. In RELEASE it works perfectly and on the emulator it works on both DEBUG and RELEASE.
As stated in the original post, calling System.WebClient.DownloadDataTaskAsync a second, third or Nth time all result in normal behaviour. It also only occur when I use a Spotify Android SDK Java binding project and call OpenLoginWindow() (which opens another activity, logs in and returns successfully) prior to calling DownloadDataTaskAsync.
EDIT: Here's my call stack.
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(System.ServiceModel.Channels.Message reply, System.ServiceModel.Channels.MessageFault fault, string action, System.ServiceModel.Channels.MessageVersion version, System.ServiceModel.Channels.FaultConverter faultConverter) + 0x124 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.HandleReply(System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, ref System.ServiceModel.Dispatcher.ProxyRpc rpc) + 0x147 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.EndCall(string action, object[] outs, System.IAsyncResult result) + 0xb2 bytes
System.ServiceModel.dll!System.ServiceModel.ClientBase.ChannelBase.EndInvoke(string methodName, object[] args, System.IAsyncResult result) + 0x1e bytes
PhoneClient.dll!PhoneClient.ServiceReference1.Service1Client.Service1ClientChannel.EndGetFirstAidGuides(System.IAsyncResult result) Line 420 C#
PhoneClient.dll!PhoneClient.ServiceReference1.Service1Client.PhoneClient.ServiceReference1.IService1.EndGetFirstAidGuides(System.IAsyncResult result) Line 284 + 0x7 bytes C#
PhoneClient.dll!PhoneClient.ServiceReference1.Service1Client.OnEndGetFirstAidGuides(System.IAsyncResult result) Line 292 + 0x2 bytes C#
System.ServiceModel.dll!System.ServiceModel.ClientBase.OnAsyncCallCompleted(System.IAsyncResult result) + 0x20 bytes
System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously) + 0x66 bytes
System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously, System.Exception exception) + 0xe bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.CallComplete(bool completedSynchronously, System.Exception exception) + 0x8 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishSend(System.IAsyncResult result, bool completedSynchronously) + 0x99 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.SendCallback(System.IAsyncResult result) + 0x1a bytes
System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously) + 0x66 bytes
System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously, System.Exception exception) + 0xe bytes
System.ServiceModel.dll!System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(System.IAsyncResult result) + 0x52 bytes
System.Windows.dll!System.Net.Browser.ClientHttpWebRequest.InvokeGetResponseCallback.AnonymousMethod__8(object state2) + 0x1b bytes
mscorlib.dll!System.Threading.ThreadPool.WorkItem.WaitCallback_Context(object state) + 0x18 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x63 bytes
mscorlib.dll!System.Threading.ThreadPool.WorkItem.doWork(object o) + 0x47 bytes
mscorlib.dll!System.Threading.Timer.ring() + 0x70 bytes
And the error: The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
I'm currenntly working on a Windows Phone 7 application in which I am communicating with a WCF service. I've made it work within one method already. So I that it is possible.
Here is my class that calls the WCF service
public partial class FirstAidGuides : PhoneApplicationPage
{
public FirstAidGuides()
{
InitializeComponent();
ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
sc.GetFirstAidGuidesCompleted += new EventHandler<ServiceReference1.GetFirstAidGuidesCompletedEventArgs>(sc_GetFirstAidGuidesCompleted);
sc.GetFirstAidGuidesAsync();
}
void sc_GetFirstAidGuidesCompleted(object sender, ServiceReference1.GetFirstAidGuidesCompletedEventArgs e)
{
FirstAidGuideText.Text = e.Result[0].Text;
}
}
Right now, I'm just trying to get some text written in a textblock, from my result.
This is the interface of the WCF service.
[ServiceContract]
public interface IService1
{
[OperationContract]
long CreateCall(string phoneNumber, double longtitude, double langtitude);
[OperationContract]
List<Model.FirstAidGuide> GetFirstAidGuides();
}
The method of my service class, that pulls data from a database.
public List<Model.FirstAidGuide> GetFirstAidGuides()
{
DataClasses1DataContext db = new DataClasses1DataContext();
var firstAidGuides = (from f in db.FirstAidGuides select f);
List<Model.FirstAidGuide> list = new List<Model.FirstAidGuide>();
foreach (var guide in firstAidGuides.ToList())
{
Model.FirstAidGuide fa = new Model.FirstAidGuide();
fa.FirstAidId = guide.FirstAidId;
fa.Title = guide.FirstAidTitle;
fa.Text = guide.FirstAidText;
fa.LastUpdated = (DateTime)guide.LastUpdated;
list.Add(fa);
}
return list;
}
And just for convenience. The FirstAidGuide class.
[DataContract]
public class FirstAidGuide
{
[DataMember]
private string _title;
[DataMember]
private string _text;
[DataMember]
private DateTime _lastUpdated;
[DataMember]
private long _firstAidId;
public long FirstAidId
{
get { return _firstAidId; }
set { _firstAidId = value; }
}
public DateTime LastUpdated
{
get { return _lastUpdated; }
set { _lastUpdated = value; }
}
public string Text
{
get { return _text; }
set { _text = value; }
}
public string Title
{
get { return _title; }
set { _title = value; }
}
}
I simply cannot get it to do anything. I'm getting a FaultException, which points me in the direction that it cannot handle the response from the WCF service.
Any help would be appreciated.
Can you try enabling tracing on your WCF Service and also inspect the trace to find out what the error is. Also set the below property to get a complete stack trace of the error
<serviceDebug includeExceptionDetailInFaults="true" />
What I tend to do over WCF is to wrap everything inside my [OperationContract] method in a Try...Catch block; unravel the stack trace of any caught exception and all inner exceptions and stick that as a string into the message of a FaultException that I then re-throw over the soap boundary. Something like this:
public static string GetDebugString(this Exception ex)
{
var builder = new StringBuilder();
GetDebugString(ex, builder);
while ((ex = ex.InnerException) != null)
{
GetDebugString(ex, builder);
}
return builder.ToString();
}
private static void GetDebugString(Exception ex, StringBuilder builder)
{
builder.AppendLine(ex.GetType().Name);
builder.AppendLine();
builder.AppendLine(ex.Message);
builder.AppendLine();
builder.AppendLine(ex.StackTrace);
builder.AppendLine();
}
[OperationContract]
public void Foo()
{
this.MakeSafeCall(() => this.UnsafeFoo());
}
public void Unsafe()
{
// do stuff
}
private void MakeSafeCall(Action action)
{
try
{
action();
}
catch (Exception ex)
{
throw new FaultException(ex.GetDebugString());
}
}
The problem was in this line:
foreach (var guide in firstAidGuides.ToList())
Apparently calling .ToList() made the whole thing crash.
Simply removing .ToList() fixed everything.