在 Service Fabric 中尝试远程处理 Actor 时,出现以下异常:“指定的转换无效。”。
我的代码如下:
actorProxy的初始化
private static Uri serviceUri = new Uri("fabric:/ServiceFabricVoting/MyTestActorService");
private static IMyTestActor myActorProxy = ActorProxy.Create<IMyTestActor>(ActorId.CreateRandom(), serviceUri);
方法调用:
var number = await myActorProxy.GetCountAsync();
Actor 实现:
[StatePersistence(StatePersistence.Persisted)]
internal class MyTestActor : Actor, IMyTestActor
{
/// <summary>
/// Initializes a new instance of MyTestActor
/// </summary>
/// <param name="actorService">The Microsoft.ServiceFabric.Actors.Runtime.ActorService that will host this actor instance.</param>
/// <param name="actorId">The Microsoft.ServiceFabric.Actors.ActorId for this actor instance.</param>
public MyTestActor(ActorService actorService, ActorId actorId)
: base(actorService, actorId)
{
}
/// <summary>
/// This method is called whenever an actor is activated.
/// An actor is activated the first time any of its methods are invoked.
/// </summary>
protected override Task OnActivateAsync()
{
ActorEventSource.Current.ActorMessage(this, "Actor activated.");
// The StateManager is this actor's private state store.
// Data stored in the StateManager will be replicated for high-availability for actors that use volatile or persisted state storage.
// Any serializable object can be saved in the StateManager.
// For more information, see https://aka.ms/servicefabricactorsstateserialization
return this.StateManager.TryAddStateAsync("count", 0);
}
/// <summary>
/// TODO: Replace with your own actor method.
/// </summary>
/// <returns></returns>
Task<int> IMyTestActor.GetCountAsync()
{
return this.StateManager.GetStateAsync<int>("count");
}
/// <summary>
/// TODO: Replace with your own actor method.
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
Task IMyTestActor.SetCountAsync(int count)
{
// Requests are not guaranteed to be processed in order nor at most once.
// The update function here verifies that the incoming count is greater than the current count to preserve order.
return this.StateManager.AddOrUpdateStateAsync("count", count, (key, value) => count > value ? count : value);
}
}
这是异常的堆栈跟踪:
" at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Common.NativeServiceCommunication.CreateServiceCommunicationClient(Guid& iid, IntPtr transportSettingsPtr, IntPtr connectionAddress, IFabricCommunicationMessageHandler notificationHandler, IFabricServiceConnectionEventHandler connectionEventHandler)\r\n at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Client.NativeServiceCommunicationClient.CreateNativeClient(FabricTransportSettings transportSettings, String connectionAddress, NativeClientConnectionEventHandler eventHandler, IServiceRemotingCallbackClient contract)\r\n at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Client.NativeServiceCommunicationClient.<>c__DisplayClass2.<.ctor>b__0()\r\n at System.Fabric.Interop.Utility.<>c__DisplayClass13.<WrapNativeSyncInvoke>b__12()\r\n at System.Fabric.Interop.Utility.WrapNativeSyncInvoke[TResult](Func`1 func, String functionTag, String functionArgs)\r\n at System.Fabric.Interop.Utility.RunInMTA(Action action)\r\n at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Client.FabricTransportServiceRemotingClientFactoryImpl.CreateClientAsync(String endpoint, CancellationToken cancellationToken)\r\n at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.<CreateClientWithRetriesAsync>d__16.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.<GetClientAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.<GetClientAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Client.FabricTransportServiceRemotingClientFactory.<Microsoft.ServiceFabric.Services.Communication.Client.ICommunicationClientFactory<Microsoft.ServiceFabric.Services.Remoting.Client.IServiceRemotingClient>.GetClientAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.<GetCommunicationClient>d__22.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.<InvokeWithRetryAsync>d__7`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Remoting.Client.ServiceRemotingPartitionClient.<InvokeAsync>d__8.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyBase.<InvokeAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyBase.<ContinueWithResult>d__7`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at VotingService.VotingService.<ProcessRequestAsync>d__4.MoveNext() in C:\\Users\\mlani\\Develop\\ServiceFabricVoting\\VotingService\\VotingService.cs:line 148"
我正在本地集群上测试该应用程序。 Actor类和Actor接口(interface)的实现都是默认的,是在项目中添加Actor服务后生成的。
感谢您的任何建议。
最佳答案
我也遇到过同样的问题。我正在从无状态服务调用 Actor 服务。问题在于无状态服务使用了不同版本的 Microsoft.ServiceFabric.Actors
nuget 包。我将版本更改为相同后,问题就消失了。
当您的 Service Fabric SDK 版本与无状态/有状态服务引用的版本不同时,可能会出现此问题。
关于exception - Service Fabric Actor 远程调用导致 "Specified cast is not valid."异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40003219/