Occasional Exception when calling a method in wcf client proxy - c#

Sometimes, on my xp machines, I get an exception when calling a method in my auto-generated client proxy. I told the debugger to stop on all clr exceptions.
Now sometimes when I call the following:
public MyStuff.Entities.Package GetPackageById(System.Guid sessionId, int packageId)
{
return base.Channel.GetPackageById(sessionId, packageId);
}
I first get an InvalidOperationException: Collection was modified...
Pressing F10 results in a FileLoadException with the following messge:
Could not load file or assembly 'System.Runtime.Serialization.resources, Version=4.0.0.0, Culture=de-DE, PublicKeyToken=b77a5c561934e089' or one of its dependencies. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)
I'm sure the service didn't throw an exception because it would show up as a FaultException. Since it's an InvalidOperationException that's being thrown when calling base.Channel.GetPackageById(sessionId, packageId) I assume it's not directly my fault?
I'm slowly running out of ideas what I could try to eliminate or work around this exception.
It never happened when using my developer machine with windows 7 and .NET 4.5 installed on it. On XP this will happen 1 out of 4 times approximately.
GetPackageById on service side looks like this:
public Package GetPackageById(Guid sessionId, int packageId)
{
try
{
return DataProvider.Provider.GetPackagesByKey(packageId,null);
}
catch (Exception ex)
{
throw new FaultException<MySericeFault>(new MySericeFault(ex));
}
}
The Package Class looks like this:
[DataContract(IsReference = true)]
[KnownType(typeof(MyApp.Entities.MachinePackage))]
public partial class Package: INotifyPropertyChanged
{
private DateTime? _outDate;
[DataMember]
public DateTime? OutDate
{
get { return _outDate; }
set
{
if (_outDate != value)
{
_outDate = value;
OnPropertyChanged("OutDate");
}
}
}
private int _productId;
[DataMember]
public int ProductId
{
get { return _productId; }
set
{
if (_productId != value)
{
_productId = value;
OnPropertyChanged("ProductId");
}
}
}
protected virtual void OnPropertyChanged(String propertyName)
{
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add { _propertyChanged += value; }
remove { _propertyChanged -= value; }
}
private event PropertyChangedEventHandler _propertyChanged;
}

This is more of an experiment but too big to put as a comment!
Try creating a new operation contract that performs this code:
Service:
public Package GetPackageByIdTest(Guid sessionId, int packageId)
{
return new Package { ProductId = packageId, OutDate = DateTime.Now };
}
Then create a console application that references your service and write something like this:
Client:
static void Main(string[] args)
{
for (int tester = 0; tester < 2000; tester++)
{
using (var service = new ConsoleApplication1.ServiceReference1.Service1Client())
{
Package result = service.GetPackageByIdTest(Guid.NewGuid(), tester);
Console.WriteLine(result.ProductId);
}
}
Console.ReadKey();
return;
}
Then, try running that on one of the known XP machines that fails and see if you get the same issue. If not it would suggest there is something going a miss in your DataProvider.Provider.GetPackagesByKey(...) method.

Related

Class Level Error Handler For DAO

I am using Entity Framework. Below is an example of a list method for an Actors context in my ActorsDao class. If you imagine my application is like imdb, there will be CRUD methods for various other contexts such as Movies, Directors, Genres, Reviews, Studios etc.
Regardless of the method or context, I handle errors in the same way. Due to my many methods across many contexts, my catch section is always exactly the same.
Obviously, I could create an error handling class, put the code in there, and just call a method in that class from the catch block.
However, I'm wondering if there a way to omit the TRY...CATCH from each method and set up a global error handler for the methods in my entity framework layer?
I would only want this global error handler to handle these errors and not errors from the rest of the application.
I seem to remember in Java Spring, you could annotate a class or method with the name of a method, and all errors would be passed to that without the need of a TRY...CATCH. I'm wondering if there is something similar for .NET (or a third party library with such functionality)?
public List<Actor> ListActors()
{
List<Actor> actorList = new List<Actor>();
using (var context = new ActorContext())
{
try
{
actorList = context.Actors.ToList<Actor>();
}
catch (Exception e)
{
//Handle error code
}
}
return actorList;
}
EDIT
I did some more research and found this code from here https://stackoverflow.com/a/4851985/1753877
private void GlobalTryCatch(Action action)
{
try
{
action.Invoke();
}
catch (ExpectedException1 e)
{
throw MyCustomException("Something bad happened", e);
}
catch (ExpectedException2 e)
{
throw MyCustomException("Something really bad happened", e);
}
}
public void DoSomething()
{
GlobalTryCatch(() =>
{
// Method code goes here
});
}
Would using a delegate like this be OK? It certainly meets my requirements.
You can create a class like this and extend the controller from this class.
Error Handler class looks like this :
package com.wes.essex.rest;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.wes.essex.bean.ErrorResponse;
public class SkyNewsController {
private static final Logger LOGGER = LoggerFactory.getLogger(SkyNewsController.class);
#ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleError(Exception ex) {
LOGGER.info("start");
LOGGER.error(ex.getMessage(), ex);
ErrorResponse error = new ErrorResponse();
error.setTimestamp(ZonedDateTime.now().format(DateTimeFormatter.ISO_INSTANT));
LOGGER.debug("error : {} ", error);
ResponseEntity<ErrorResponse> response = null;
if (ex instanceof ConstraintViolationException) {
error.setReasonCode(HttpStatus.BAD_REQUEST.value());
ConstraintViolationException constraintException = (ConstraintViolationException) ex;
Set<ConstraintViolation<?>> set = constraintException.getConstraintViolations();
String errorMessage = "Input Validation Failed:";
for (ConstraintViolation<?> constraintViolation : set) {
errorMessage += constraintViolation.getMessageTemplate() + ",";
}
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
error.setErrorMessage(errorMessage);
response = new ResponseEntity<ErrorResponse>(error, HttpStatus.BAD_REQUEST);
} else {
error.setReasonCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
error.setErrorMessage(ex.getMessage());
response = new ResponseEntity<ErrorResponse>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
return response;
}
}
This would be the baean class for error response :
package com.wes.essex.bean;
public class ErrorResponse {
private static final long serialVersionUID = 5776681206288518465L;
private String timestamp;
private String errorMessage;
private int reasonCode;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public int getReasonCode() {
return reasonCode;
}
public void setReasonCode(int reasonCode) {
this.reasonCode = reasonCode;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}

Exception thrown: 'System.MissingMethodException'

I'm working in a WinForm app in 4 layers:
DAL (Data access)
BOL (Bussiness objects)
BAL (Bussiness access)
INT (Intermediate access).
I'm using the Intermediate layer to run any operation needed by the Presentation layer, trying to make it independent, as we can use it in a WinForm, ASP, and so.
I've created a Class that executes those operations like this:
// Clase: ProjectStatusMID
using System.Collections.Generic;
namespace Trevo.FrameWork
{
public class ProjectStatusMID
{
#region Propiedades
private ProjectStatusBOL _Data = new ProjectStatusBOL();
private ProjectStatusBAL _Operations = new ProjectStatusBAL();
private Acciones _Action = Acciones.Nada;
#endregion Propiedades
public ProjectStatusBOL Data
{
get { return _Data; }
set
{
_Data = value;
}
}
public ProjectStatusBAL Operations
{
get { return _Operations; }
set
{
_Operations = value;
}
}
public Acciones Action
{
get { return _Action; }
set
{
_Action = value;
}
}
public int IDProject
{
get { return _Data.IDProject; }
set
{
_Data.IDProject = value;
}
}
public List<Codigos> ProjectsList
{
get { return LoadProjects(); }
}
public ProjectStatusMID()
{
//Load();
}
public void Load()
{
Operations.Consultar(Data);
}
public List<Codigos> LoadProjects()
{
List<Codigos> oRet = new List<Codigos>();
MyProjectsBAL _Operations = new MyProjectsBAL();
MyProjectsBOL _Data = new MyProjectsBOL();
List<MyProjectsBOL> _MyList = _Operations.Lista(_Data);
foreach (MyProjectsBOL o in _MyList)
{
oRet.Add(new Codigos(o.IDProject, o.Project));
}
return oRet;
}
}
}
// Clase: ProjectStatusMID
At the front-end (in this case is WinForm), we are instancing this class as follows:
ProjectStatusMID OO = new ProjectStatusMID();
So, the issue comes when calling one of the methods:
parProject.DataSource = OO.LoadProjects();
Everything is referenced, the app compiles without any problems, the project that contains the class is part of the solution in a separated project (as any other layer), BUT we have the following error:
System.MissingMethodException occurred
HResult=-2146233069
Message=Método no encontrado: 'System.Collections.Generic.List`1 Trevo.FrameWork.ProjectStatusMID.LoadProjects()'.
Source=WorkLoadPresentation
StackTrace:
en Trevo.FrameWork.PS_ProjectStatus_Datos.CargarListas()
en Trevo.FrameWork.PS_ProjectStatus_Datos.PS_ProjectStatus_Datos_Load(Object sender, EventArgs e) en C:\Users\fbravo\OneDrive\Particular_Sistemas\WorkLoad\WorkLoadPresentation\ProjectStatus\PS_ProjectStatus_Datos.cs:línea 25
InnerException:
I've tried to make the class static, re-creating the entire app, deleting the GAC, and so, but a week loose trying different things.
Any help will be appreciated
Could be several issues. The most common one is that you included the DLL library which is the wrong version (e.g. without the method that's missing). Easiest thing to do is to open the exe in the decompiler (e.g. Reflector) and step through it.
Another issue could be the wrong bitness (but probably not).
You have to make sure you referenced the external project dll in your main Winforms application

VS 2015 Transaction Response Times much higher than SilkPerformer

I have some relatively simple transactions that run against my application like "start user session" which typically takes a couple seconds when running a VS project through SilkPerformer. When I try to execute the same transaction using the VS 2015 performance testing tools (locally on the controller) the response times are roughly twelve seconds longer, repeatedly.
I have a transaction logger that captures the response times of each transaction so I can see them individually during the execution in VS and I'm wondering if I'm missing a setting somewhere or there is a configuration change I can make to the project because it almost seems as if the project is pacing the execution of the transactions. I get the same behavior whether running on an agent or the controller directly so it doesn't appear to be network related.
This is a sample of the code that's executing:
public interface ITestTransactionTimer : IDisposable { }
public class TestTransactionTimer : ITestTransactionTimer
{
public TestContext TestContext { get; private set; }
public string TransactionName { get; private set; }
public TestTransactionTimer(TestContext testContext, string transactionName)
{
this.TestContext = testContext;
this.TransactionName = transactionName;
this.TestContext.BeginTimer(this.TransactionName);
}
public void Dispose()
{
this.TestContext.EndTimer(this.TransactionName);
}
}
public class NoOpTestTransactionTimer : ITestTransactionTimer
{
public void Dispose() { }
}
protected ITestTransactionTimer LogTransaction(string transactionName)
{
if ((null == this.TestContext) || !this.TestContext.Properties.Contains("$LoadTestUserContext"))
{
return new NoOpTestTransactionTimer();
}
return new TestTransactionTimer(this.TestContext, transactionName);
}
private TestContext testContextInstance;
public TestContext TestContext
{
get { return testContextInstance; }
set { testContextInstance = value; }
}
//starting User Session
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "C:\\Path\\Data.csv", "Data#csv", DataAccessMethod.Sequential), DeploymentItem("C:\\Path\\Data.csv"), TestMethod]
public void smokeTest()
{
sUserName = "domain\\"+TestContext.DataRow["user"].ToString();
sPassword = TestContext.DataRow["password"].ToString();
prospectClientId = TestContext.DataRow["prospectClientId"].ToString();
accountNumber = TestContext.DataRow["accountNumber"].ToString();
correlationId = "startUserSession - " + obj.ToString();
// Start User Session
using (this.LogTransaction("t1_startUserSession"))
{
ChannelFactory<IAppShellService> cfsus = null;
try
{
using (ChannelBuilder.mPContext(ref appShellServiceClient, "IAppShellService", sUserName, sPassword, 0, null, correlationId, false, effectiveDate, ref cfsus))
{
var userSessionResult = appShellServiceClient.StartUserSession();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
finally
{
cfsus.Close();
}
}
}
The only call of EndTimer is in the Dispose method and that is not called explicitly in your code. Hence the Dispose method will only be called when the garbage collector wants to call it.
I believe you need to add an explicit call of EndTimer. Perhaps by adding a call of your Dispose method into the finally block. See also this answer.

StackExchange.Redis ConnectionMultiplexer - handling disconnects

What is the correct way to handle socket failure in a ConnectionMultiplexer? I know it will try again silently in the background, but is there any accepted canonical way to handle the time between such disconnects? Since I wrap this up in our own client anyway, I was thinking something like the following:
private async Task<IDatabase> GetDb(int dbToGet)
{
int numberOfRetries = 0;
while (!multiplexer.IsConnected && numberOfRetries < MAX_RETRIES)
{
await Task.Delay(20);
numberOfRetries++;
}
if (!multiplexer.IsConnected)
{
// Panic, die, etc.
}
// Continue as though connected here
}
It seems a bit clumsy, though, so I'm wondering if there's a better way to handle this.
(This is all in version 1.0.414 of StackExchange.Redis, the latest version from NuGet)
I just wrapped multiplexer,
by default it has auto reconnect definition,
the real problem is that you have subscribe/Psubscribe to Redis with current socket connection,
therefore I used the ConnectionRestored Event to re-Register the subscribe patterns to the relevant channels/actions.
Class Example:
public class RedisInstanceManager
{
public RedisInstanceCredentials m_redisInstanceCredentials { get; set; }
public DateTime? m_lastUpdatedDate { get; set; }
public ConnectionMultiplexer redisClientsFactory { get; set; }
public Timer _ConnectedTimer;
public Action _reconnectAction;
public RedisInstanceManager(ConnectionMultiplexer redisClients, Action _reconnectActionIncoming)
{
string host,port;
string[] splitArray = redisClients.Configuration.Split(':');
host = splitArray[0];
port = splitArray[1];
this.redisClientsFactory = redisClients;
this.m_redisInstanceCredentials = new RedisInstanceCredentials(host, port);
this.m_lastUpdatedDate = null;
_ConnectedTimer = new Timer(connectedTimer, null, 1500, 1500);
_reconnectAction = _reconnectActionIncoming;
this.redisClientsFactory.ConnectionRestored += redisClientsFactory_ConnectionRestored;
}
private void connectedTimer(object o)
{
_ConnectedTimer.Change(Timeout.Infinite, Timeout.Infinite);
if (!this.redisClientsFactory.IsConnected)
{
Console.WriteLine("redis dissconnected");
}
_ConnectedTimer.Change(1500,1500);
}
void redisClientsFactory_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
Console.WriteLine("Redis Connected again");
if (_reconnectAction != null)
_reconnectAction();
}
public ConnectionMultiplexer GetClient()
{
return this.redisClientsFactory;
}
}

WCF for windows phone 8.1 silverlight

I'm having problem using wcf with wp8.1 silverlight. I countinously getting the error The contract 'IPhoneService' contains synchronous operations, which are not supported in Silverlight. Split the operations into "Begin" and "End" parts and set the AsyncPattern property on the OperationContractAttribute to 'true'. Note that you do not have to make the same change on the server. After I changed my syncronous method to async I'm still getting the same error (I updated the service reference.). Out of curiousity I tried to use it on a console app, and it works perfectly.
Previously I did get an another error that might have something to do with it. Adding a service reference generated an app.config file, but the app needed a ServiceReferences.ClientConfig, so I simply renamed it.
For now I changed back the WCF method to syncronous:
public int GetData()
{
return 12;
}
and on my MainViewModel (I'm using MVVMLight toolkit):
public void Load()
{
var client = new ServiceReference1.PhoneServiceClient();
client.GetDataCompleted += client_GetDataCompleted;
client.GetDataAsync();
}
void client_GetDataCompleted(object sender, ServiceReference1.GetDataCompletedEventArgs e)
{
Title = e.Result.ToString();
}
and i implemeneted before the async method like this, getting the same error anyway:
public IAsyncResult BeginGetData(AsyncCallback callback, object asyncState)
{
var msg = 12;
return new CompletedAsyncResult<int>(msg);
}
public int EndGetData(IAsyncResult r)
{
CompletedAsyncResult<int> result = r as CompletedAsyncResult<int>;
return result.Data;
}
class CompletedAsyncResult<T> : IAsyncResult
{
T data;
public CompletedAsyncResult(T data)
{ this.data = data; }
public T Data
{ get { return data; } }
#region IAsyncResult Members
public object AsyncState
{ get { return (object)data; } }
public WaitHandle AsyncWaitHandle
{ get { throw new Exception("The method or operation is not implemented."); } }
public bool CompletedSynchronously
{ get { return true; } }
public bool IsCompleted
{ get { return true; } }
#endregion
}
The problem was VS2013 RC2 version. The reference wasn't generated correctly. An update solved the problem

Categories

Resources