使用服务引用时无法将IAsyncResult转换为AsyncResult

时间:2010-03-12 20:23:51

标签: c# .net wcf asynchronous

我正在运行WCF服务,我在解决方案资源管理器中使用“添加服务引用”添加了对服务的引用,并选中了“创建异步操作”框。

我的通话工作正常,我有一个双向通道,从服务器报告一些事件,我收到了事件。但是,当异步任务在我的回调handeler中完成时,我收到错误Unable to cast object of type 'SendAsyncResult' to type 'System.Runtime.Remoting.Messaging.AsyncResult'.

调用该方法的代码。

DatabaseManagement.DatabaseManagementClient d = new DatabaseManagement.DatabaseManagementClient(new InstanceContext(new DatabaseManagementCallback()));
d.Open();
d.BeginCreateDatabase("", "PreConfSA", "_test", new AsyncCallback(BeginCreateDatabaseCallback), null);

异步回调

static void BeginCreateDatabaseCallback(IAsyncResult ar)
{
    AsyncResult result = (AsyncResult)ar; //Execption happens here
    DatabaseManagement.DatabaseManagementClient caller = (DatabaseManagement.DatabaseManagementClient)result.AsyncDelegate;
    Console.WriteLine(caller.EndCreateDatabase(ar));
    DatabaseManagement.AccountInfo ai = new DatabaseManagement.AccountInfo();
    //set up ai here
    Console.WriteLine(caller.UpdateInfo("", "_test", ai));
}

执行细节

System.InvalidCastException was unhandled by user code
  Message=Unable to cast object of type 'SendAsyncResult' to type 'System.Runtime.Remoting.Messaging.AsyncResult'.
  Source=Sandbox Console
  StackTrace:
       at Sandbox_Console.Program.BeginCreateDatabaseCallback(IAsyncResult ar) in E:\Visual Studio 2010\Projects\Sandbox Console\Program.cs:line 26
       at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
  InnerException: 

我真的不需要EndCreateDatabase的结果,但我读到的每个地方都说你必须调用EndYouFunctionHere()或者发生不好的事情。

任何推荐?

1 个答案:

答案 0 :(得分:4)

为服务引用生成的EndXxx方法具有签名:

EndXxx(IAsyncResult result);

(至少他们在我的环境中做过 - 你看到的是不同的东西吗?)

因此,您实际上不需要执行强制转换以调用EndXxx方法。

但是,在这种情况下,你需要一些方法来将服务引用(客户端实例)引入回调方法,因为你无法使用AsyncResult.AsyncDelegate来获取它。您可以通过将代理对象存储在成员变量而不是局部变量中,或者将其作为asyncState传递给BeginXxx方法来执行此操作:

d.BeginCreateDatabase("", "PreConfSA", "_test",
  new AsyncCallback(BeginCreateDatabaseCallback),
  d);  // passing d as asyncState instead of null

然后从回调中的IAsyncResult.AsyncState中检索它:

DatabaseManagement.DatabaseManagementClient caller =
  (DatabaseManagement.DatabaseManagementClient)ar.AsyncState;

这消除了有关IAsyncResult的具体实现的任何假设。