首页 文章

抛出错误异常时,WPF自托管应用程序中的WCF服务崩溃(异步方法)

提问于
浏览
0

我有一个服务托管在WPF应用程序中,带有使用Begin / end方法的异步方法,当我在服务中捕获异常时,我想抛出一个faultException来警告客户端 .

但是,当我尝试抛出faultException时,主机应用程序崩溃,突然关机 .

在我的存储库中,我捕获了UpdateException,然后,我创建了一个自定义异常,即UniqueKeyException,它抛出给调用者 . 调用者是一种在Begin方法中调用的辅助方法 .

这个辅助方法,捕获UniqyeKeyException并且只执行“throw”,即在我的end方法的try / catch块中捕获 . 这里有一些我不明白的东西,为什么最终mehod这个异常被捕获在AgregateException块而不是UniqueKeyException .

好吧,无论如何,在end方法的catch块中,在AgregateException块中,我检查innerException是否为UniqueKeyException,如果为true,我创建一个对象UniqueKeyArgs(一个自定义类,其中包含要发送给客户端的信息),创建一个FaultException,最后抛出FaultException . 正是在这一步中,抛出,主机应用程序崩溃 .

我认为我已正确配置,因为我的自定义类UniqueKeyArgs被装饰为Datacontract,其属性为DataMember,在我的主机应用程序的app.config中我配置行为以包含异常细节,在 Contract 中我用faultContract装饰它 .

为什么应用程序崩溃?

我的代码如下:

REPOSITORY

public List<Usuers> updateUsers(List<Users> paramUsers)
{
....

catch(UpdateException ex)
{
SqlException innerEx = (SqlException)ex.InnerException;

                //Code 2627 is Unique Key exception from SQL Server.
                if (innerEx != null && innerEx.Number == 2627)
                {
                    //I create the conditions of searching
                    ConditionsUsers conditions = new conditions();

                    conditions.UserName = (Users)ex.StateEntries[0].Entity).userName;

                    //Search for the existing user
                    Users myUser = getUser(conditions);
                    string message = "the user " + conditions.userName + " exists.";
                    throw new UniqueKeyException(message, myUser);
                }
                throw;
}

服务实施

//This is my auxiliar method, called in the Begin method.
private submitUpdates()
{
     ....

     catch(UniqueKeyException ex)
     {
          //The code enter here
          throw;
     }
}



public IAsyncResult BeginUpdateUsers(List<users> paramUsers, AsyncCallback callback, object state)
{
     Task<List<Users>> myTask= Task<List<Users>>.Factory.StartNew(p => sumbmitUpdates(paramUsers), state);
     return myTask.ContinueWith(res => callback(myTask));
}


public List<Users> EndUpdateusers(IAsyncResult result)
     {
          try
          {
               return ((Task<List<Users>>)result).Result;
          }
          //Why agregateException and not is catched in  the UniqueKeyException ???
          catch(AgregateException ex)
          {
               if (innerExceptions[0] is UsuariosValorUnicoException)
                    {
                        //I assign manually the data to debug, to discard other problems.
                        Users myUser = new Users();
                        myUser.UserName = "Jhon";
                        myUser.Password = "pass123";
                        UniqueKeyArgs myArgs = new UniqueUserArgs("unique key error", myUser);
                        FaultException<UniqueKeyArgs> myException = new FaultException<UniqueKeyArgs>(myArgs);

                        //Crash here, in the throw myException
                        throw myException;                        
                    }
                }
                throw;
          }

我的 Contract

[FaultContract(typeof(UniqueKeyArgs))]
IAsyncResult BeginUpdateUsers(List<Users> paramUser, AsyncCallback callback, object state);
List<Users> EndUpdateUsers(IAsyncResult result);

在End方法中抛出myException时崩溃 .

我在post中看到解决方案也是在主机应用程序中捕获异常,而不仅仅是在服务对象中 . 但是,此解决方案使用Application.ThreadException,它属于System.Windows.Forms命名空间,我使用的是WPF应用程序 .

如何从WPF应用程序中托管的服务向客户端发送异常?

谢谢 .

EDIT1:好吧,我在抛出异常的行中使用了try / catch块,我发现错误是我没有说明原因,所以当我创建FaultException时,我会:

FaultException<UniqueKeyArgs> myException = new FaultException<UniqueKeyArgs>(myArgs, new FaultReason("DummyReason");

在这种情况下,异常消息是“DummyReason”,我在FaultReason中设置的消息,所以它什么也没说 . FaultException不是throw,并将泛型异常抛给客户端 .

在这种情况下,主机应用程序不会关闭,但关闭与客户端的连接,我必须重新连接 .

似乎问题是FaultException的创建者,但我没有看到问题 .

@Roeal建议也许只能使用带有synch方法的faultException,但在这个link中我可以看到一个与异步方法一起使用的例子 . 我见过别人的例子,不是唯一的 .

谢谢 .

编辑2:我解决了我的问题 . 我的问题是在FaultException中,T是一个具有自我跟踪实体属性的对象,这是一个问题,如果我没有错,我只能使用基本类型作为异常的属性 .

然后,在例外情况下,我发现了ISerialize . 它需要能够将信息发送到客户端,如果没有这个,客户端会收到异常 . 具有null属性的详细信息 .

2 回答

  • 1

    我解决了我的问题 . 我的问题是在FaultException中,T是一个具有自我跟踪实体属性的对象,这是一个问题,如果我没有错,我只能使用基本类型作为异常的属性 .

    然后,在例外情况下,我发现了ISerialize . 它需要能够将信息发送到客户端,如果没有这个,客户端会收到异常 . 具有null属性的详细信息 .

  • 0

    您是否还在服务 Contract 中声明了同步操作?在这种情况下,也许这会有所帮助:

    如果在服务操作 Contract 上定义了故障 Contract ,则应仅对同步操作应用FaultContract属性 . - Juval Lowy,“编程WCF服务第3版”(第456页)

相关问题