使用服务结构时出现System.Runtime.InteropServices.COMException

时间:2017-09-05 12:28:35

标签: c# azure asp.net-web-api azure-service-fabric

我正在Azure Service Fabric Web API中创建一个应用程序,我面临以下问题:

例外:

System.Runtime.InteropServices.COMException occurred
  ErrorCode=-2146233628
  HResult=-2146233628
  Message=Field of ByRef type. (Exception from HRESULT: 0x801312E4)
  Source=mscorlib
  StackTrace:
       at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
       at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
       at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
       at Microsoft.ServiceFabric.Services.Remoting.Builder.MethodBodyTypesBuilder.BuildRequestBodyType(ICodeBuilderNames codeBuilderNames, CodeBuilderContext context, MethodDescription methodDescription)
       at Microsoft.ServiceFabric.Services.Remoting.Builder.MethodBodyTypesBuilder.Build(ICodeBuilderNames codeBuilderNames, CodeBuilderContext context, MethodDescription methodDescription)
       at Microsoft.ServiceFabric.Services.Remoting.Builder.MethodBodyTypesBuilder.Build(InterfaceDescription interfaceDescription)
       at Microsoft.ServiceFabric.Services.Remoting.Builder.CodeBuilder.Microsoft.ServiceFabric.Services.Remoting.Builder.ICodeBuilder.GetOrBuildMethodBodyTypes(Type interfaceType)
       at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
       at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyGeneratorBuilder`2.Build(Type proxyInterfaceType, IEnumerable`1 interfaceDescriptions)
       at Microsoft.ServiceFabric.Services.Remoting.Builder.CodeBuilder.Microsoft.ServiceFabric.Services.Remoting.Builder.ICodeBuilder.GetOrBuildProxyGenerator(Type interfaceType)
       at Microsoft.ServiceFabric.Services.Remoting.Builder.ServiceCodeBuilder.GetOrCreateProxyGenerator(Type serviceInterfaceType)
       at Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory.CreateServiceProxy[TServiceInterface](Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, String listenerName)
       at Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxy.Create[TServiceInterface](Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, String listenerName)
       at WebService.Controllers.HomeController.<GetAsync>d__0.MoveNext() in C:\Users\shkulka\Documents\Visual Studio 2015\Projects\SortingApp\WebService\Controllers\HomeController.cs:line 17
  InnerException: 

发生异常的行:

    IRequestManagerService proxy = ServiceProxy.Create<IRequestManagerService>(new Uri("fabric:/SortingApp/RequestManagerService"));

一些参考代码:

namespace WebService.Controllers
{
    [Route("api/[controller]")]
    public class HomeController : Controller 
    {
        [HttpGet]
        public async Task<IActionResult> GetAsync(int opId, string sortType = "Quick", string guid="454", string commaSeperatedArray="1,2,3,4")
        {
            IRequestManagerService proxy = ServiceProxy.Create<IRequestManagerService>(new Uri("fabric:/SortingApp/RequestManagerService"));
           //rest of the code continues . . . 

点击以下网址时发生异常:

http://localhost:8792/api/home?opId=0&sortType=Quick&guid=12&commaSeperatedArray=1,2,3,4

我正在使用管理员权限运行我的项目。整个解决方案中的平台目标是x64。

如何摆脱异常?

更新1:

在点击网址之前,我可以观察以下有关服务架构的信息。

在服务架构资源管理器中:

enter image description here

在“诊断事件”窗口中:

    {
  "Timestamp": "2017-09-06T10:49:34.7442479+05:30",
  "ProviderName": "Microsoft-ServiceFabric-Services",
  "Id": 2,
  "Message": "RunAsync has been cancelled for a stateful service replica.  The cancellation will be considered 'slow' if RunAsync does not halt execution within 4000 milliseconds.  Application Type Name: GettingStartedApplicationType, Application Name: fabric:/GettingStartedApplication, Service Type Name: MyActorServiceType, Service Name: fabric:/GettingStartedApplication/MyActorService, Partition Id: 097c837b-857e-4f10-8c3a-8a902c1f0bb6, Replica Id: 131491461074099453",
  "ProcessId": 34840,
  "Level": "Informational",
  "Keywords": "0x0000F00000000000",
  "EventName": "StatefulRunAsyncCancellation",
  "ActivityID": null,
  "RelatedActivityID": null,
  "Payload": {
    "applicationTypeName": "GettingStartedApplicationType",
    "applicationName": "fabric:/GettingStartedApplication",
    "serviceTypeName": "MyActorServiceType",
    "serviceName": "fabric:/GettingStartedApplication/MyActorService",
    "partitionId": "097c837b-857e-4f10-8c3a-8a902c1f0bb6",
    "replicaId": 131491461074099453,
    "slowCancellationTimeMillis": 4000.0
  }
}

{
  "Timestamp": "2017-09-06T10:49:34.760793+05:30",
  "ProviderName": "Microsoft-ServiceFabric-Services",
  "Id": 2,
  "Message": "RunAsync has been cancelled for a stateful service replica.  The cancellation will be considered 'slow' if RunAsync does not halt execution within 4000 milliseconds.  Application Type Name: GettingStartedApplicationType, Application Name: fabric:/GettingStartedApplication, Service Type Name: MyActorServiceType, Service Name: fabric:/GettingStartedApplication/MyActorService, Partition Id: 78f9a969-4f09-4d8b-932f-4962cce7f4cd, Replica Id: 131491461074094464",
  "ProcessId": 27832,
  "Level": "Informational",
  "Keywords": "0x0000F00000000000",
  "EventName": "StatefulRunAsyncCancellation",
  "ActivityID": null,
  "RelatedActivityID": null,
  "Payload": {
    "applicationTypeName": "GettingStartedApplicationType",
    "applicationName": "fabric:/GettingStartedApplication",
    "serviceTypeName": "MyActorServiceType",
    "serviceName": "fabric:/GettingStartedApplication/MyActorService",
    "partitionId": "78f9a969-4f09-4d8b-932f-4962cce7f4cd",
    "replicaId": 131491461074094464,
    "slowCancellationTimeMillis": 4000.0
  }
}

点击网址后:

enter image description here

更新2:

接口:

namespace RequestManagerService.Interfaces
{
    public interface IRequestManagerService : IService
    {
        Task submitSortRequest(string sortType, string guid, string commaSeperatedArray);
        Task<bool> isSortingComplete(string guid);
        Task<string> getSortedArray(string guid);
        Task<bool> isSortRequested(string sortType, ref string commaSeperatedArray, ref string guid);
        Task setSortResult(string sortType, string guid, string sortedArray);
    }
}

接口实现:

namespace RequestManagerService
{
    /// <summary>
    /// An instance of this class is created for each service instance by the Service Fabric runtime.
    /// </summary>
    internal sealed class RequestManagerService : StatelessService, IRequestManagerService
    {
        // <guid,<sorttype, array, isSortComplete>>
        Dictionary<string, Tuple<string, string, bool>> SortDictionary = new Dictionary<string, Tuple<string, string, bool>>(); 
        public RequestManagerService(StatelessServiceContext context)
            : base(context)
        {

        }

        public async Task<string> getSortedArray(string guid)
        {
            Tuple<string, string, bool> tempTuple;
            string sortedArray= "";

            if (await isSortingComplete(guid))
            {
                SortDictionary.TryGetValue(guid, out tempTuple);
                sortedArray = tempTuple.Item2;
            }
            else
            {
                sortedArray = "Either there no request with this guid or the sorting is not yet complete.";
            }
            return sortedArray;
        }

        public Task<bool> isSortingComplete(string guid)
        {
            bool isSortComplete = false;
            Tuple<string, string, bool> tempTuple;

            if (SortDictionary.ContainsKey(guid)) {
                SortDictionary.TryGetValue(guid, out tempTuple);
                isSortComplete = tempTuple.Item3;
            }

            return Task.FromResult(isSortComplete);
        }

        public Task<bool> isSortRequested(string sortType, ref string commaSeperatedArray, ref string guid)
        {
            bool requestFound = false;

            foreach(KeyValuePair<string, Tuple<string, string, bool>> entry in SortDictionary)
            {
                if (entry.Value.Item1 == sortType && entry.Value.Item3 == false)
                {
                    commaSeperatedArray = entry.Value.Item2;
                    guid = entry.Key;
                    requestFound = true;
                    break;
                }
            }

            return Task.FromResult(requestFound);
        }

        public Task setSortResult(string sortType, string guid, string sortedArray)
        {
            if (SortDictionary.ContainsKey(guid))
            {
                Tuple<string, string, bool> updatedTuple = new Tuple<string, string, bool>(sortType, sortedArray, true);
                SortDictionary[guid] = updatedTuple;
            }
            return Task.FromResult<object>(null);
        }

        public Task submitSortRequest(string sortType, string guid, string commaSeperatedArray)
        {
            Tuple<string, string, bool> tuple = new Tuple<string, string, bool>(sortType, commaSeperatedArray, false);
            SortDictionary.Add(guid, tuple);
            return Task.FromResult<object>(null);
        }

        /// <summary>
        /// Optional override to create listeners (e.g., TCP, HTTP) for this service replica to handle client or user requests.
        /// </summary>
        /// <returns>A collection of listeners.</returns>
        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new ServiceInstanceListener[1] {
                new ServiceInstanceListener(this.CreateServiceRemotingListener)
            };
        }

        /// <summary>
        /// This is the main entry point for your service instance.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            // TODO: Replace the following sample code with your own logic 
            //       or remove this RunAsync override if it's not needed in your service.

            long iterations = 0;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);

                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我会说这里的合约不支持ref / out参数。理想情况下,您的服务联系人不应该依赖于语言特定的工件。摆脱它们,事情应该正常。