tags:

views:

51

answers:

2

I have a service that implement the Async pattern:

[OperationContract(AsyncPattern = true)]
IAsyncResult BeginLoadDocument(Byte[] value, AsyncCallback callback, object state);

Boolean EndLoadDocument(IAsyncResult asyncResult);

The "BeginLoadDocument" run a private method "CallBack" in the service side using a ThreadPool:

public IAsyncResult BeginLoadDocument(string id, AsyncCallback callback, object state)
    {
            PendingAsyncResult<string> asyncResult =
            new PendingAsyncResult<string>(id, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Callback), asyncResult);
            return asyncResult;
    }

the Callback method load the document and set the result for the "EndLoadDocument".

So far so good, but how I can handle the exceptions?

If I throw an excetion in the server side, I get a FaultedException'1 wasn't handled. I did try to use the attribute [FaultContract(typeof(InforError))] where "InfoError" is my custum DataMember, but it does not work.

I am building the proxy using the svcutil /a http:....

A: 

You can catch an exception client-side as follows:

try {
    MyClient.MyCall();
}

catch (FaultException<IOException> exc) {
    //  Log and handle exception
}

Where the real exception thrown was, in this example, an IOException.

You'll also need a FaultContract, as you indicated you are, on the Service Interface, as such:

[ServiceContract]
public interface IMyService {

    [OperationContract]
    [FaultContract(typeof(IOException))]
    void MyCall();    
}


** EDIT **

I'm a little fuzzy on something you wrote:

[FaultContract(typeof(InforError))] where "InfoError" is my custum DataMember

What do you mean by 'DataMember'? What's the definition for InfoError?

The [FaultContract] should be defined on the service interface method... in your post you sound like you're trying to add it to the client side; this is not correct. If I modify your example code, it would look like:

[ServiceContract]
public interface IMyService {

    [OperationContract(AsyncPattern = true)] 
    [FaultContract(typeof(InfoErrorException))]
    IAsyncResult BeginLoadDocument(Byte[] value, AsyncCallback callback, object state);   

    string EndLoadDocument(IAsyncResult asyncResult); 

If your service interface is decorated as such, the client should be able to receive FaultExceptions when you call EndLoadDocument (provided the exception that was thrown was an InfoErrorException exception).

On the server side, you have to trap exceptions, then wrap them in a FaultException, as such:

catch (IOException exp) {
    InfoErrorException myException = new InfoErrorException();
    myException.Reason = "I failed:  " + exp.Message;
    throw new FaultException<InfoErrorException>(myException);
}

I believe (but would have to double-check) that you can also catch a FaultException on the client side without specifying the type... similar to catching the generic System.Exception.

Your try...catch for the FaultException should be in your callback, around the statement to call EndLoadDocument().

James B
My interface as the async signature :[ServiceContract] public interface IMyService {[OperationContract(AsyncPattern = true)] IAsyncResult BeginLoadDocument(Byte[] value, AsyncCallback callback, object state); Boolean EndLoadDocument(IAsyncResult asyncResult);}I do use the Try-Catch in the client side, the issue is in the server side, where the expection is not handle it. If I use a Try-Catch in the server side the client will never know about the Exception, if I do not use the try-catch the error stop the service and the client is not receiving anything.
A: 

Thanks, but the issue is different. My service interface is:

[ServiceContract]
public interface IMyService
{
[OperationContract(AsyncPattern = true)] 
IAsyncResult BeginLoadDocument(Byte[] value, AsyncCallback callback, object state); 

      string EndLoadDocument(IAsyncResult asyncResult); 

}

[DataContract] public class InforError { [DataMember] public string Message { get; set; } }

The implementation is:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, IncludeExceptionDetailInFaults = true)] public class Myervice : IMyService { public IAsyncResult BeginLoadDocument(string id, AsyncCallback callback, object state) { PendingAsyncResult asyncResult = new PendingAsyncResult(id, callback, state); ThreadPool.QueueUserWorkItem(new WaitCallback(Callback), asyncResult); return asyncResult; } Public string EndLoadDocument(IAsyncResult iar) { PendingAsyncResult asyncResult = iar.AsyncState as PendingAsyncResult; return asyncResult.result; } void Callback(Object state) { // do something here to load the document and the Result } }

Because my service is implementing the Async pattern I do not know where add the [FaultContract(typeof(IOException))] attribute, because the callback is just a private method no part of the service.

Using the attribute for the Fault Exception in the BeginLoadDocument or EndLoadDocument doesn't work.

I am using the svcutil to build the proxy with /async

Any idea in what it is the solution?

This should be more of an update to your question instead of an answer.
David Hoerster