Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Dynamics CRM插件中:如何强制代码不等待异步响应_C#_Asynchronous_Async Await_Dynamics Crm_Azure Functions - Fatal编程技术网

C# 在Dynamics CRM插件中:如何强制代码不等待异步响应

C# 在Dynamics CRM插件中:如何强制代码不等待异步响应,c#,asynchronous,async-await,dynamics-crm,azure-functions,C#,Asynchronous,Async Await,Dynamics Crm,Azure Functions,这是我的设想。我必须通过Dynamics CRM插件代码(C#)异步调用Azure函数,这很好。但是我不希望代码等待Azure函数的响应。我只想完成代码执行并退出 Azure功能将在必要时处理CRM中的更新 我不想等待的原因是在CRM Online中完成插件执行有2分钟的时间限制。但是,Azure功能可能需要几分钟才能完成此过程 下面是我的插件类代码,它正在同步调用Azure函数。(我可以在下面的文档中将调用转换为异步,但按照这种方法,我的代码仍将等待响应) 您需要两个函数 函数#1将由您的插件

这是我的设想。我必须通过Dynamics CRM插件代码(C#)异步调用Azure函数,这很好。但是我不希望代码等待Azure函数的响应。我只想完成代码执行并退出

Azure功能将在必要时处理CRM中的更新

我不想等待的原因是在CRM Online中完成插件执行有2分钟的时间限制。但是,Azure功能可能需要几分钟才能完成此过程

下面是我的插件类代码,它正在同步调用Azure函数。(我可以在下面的文档中将调用转换为异步,但按照这种方法,我的代码仍将等待响应)


您需要两个函数

函数#1将由您的插件调用(基本上就是您现在所做的)。它将验证输入。如果输入成功,它将把一条消息(可能包括来自调用者的相关数据)放在一个列表中。在服务总线队列上放置消息后,它将终止并向调用者返回一条成功消息(即插件代码)

函数#2将由Azure服务总线队列消息触发。此函数将根据消息内容(来自函数#1)处理长时间运行的代码

:

此模式通常使用,因为它提供事务执行安全性。如果您只有一个函数,如上所述,并且函数失败,那么调用将丢失,因为没有要完成的侦听器


使用两个函数,我们就有了安全性。如果函数#1失败(验证或在队列中放置消息),调用者将失败,您的插件代码可以根据需要进行处理。如果函数#2失败,它将返回服务总线并排队等待重试(默认情况下,它最多重试5次,然后写入毒药队列。)

您需要两个函数

函数#1将由您的插件调用(基本上就是您现在所做的)。它将验证输入。如果输入成功,它将把一条消息(可能包括来自调用者的相关数据)放在一个列表中。在服务总线队列上放置消息后,它将终止并向调用者返回一条成功消息(即插件代码)

函数#2将由Azure服务总线队列消息触发。此函数将根据消息内容(来自函数#1)处理长时间运行的代码

:

此模式通常使用,因为它提供事务执行安全性。如果您只有一个函数,如上所述,并且函数失败,那么调用将丢失,因为没有要完成的侦听器


使用两个函数,我们就有了安全性。如果函数#1失败(验证或在队列中放置消息),调用者将失败,您的插件代码可以根据需要进行处理。如果函数#2失败,它将返回服务总线并排队等待重试(默认情况下,它最多重试5次,然后写入有毒队列。)

我对这个问题感到困惑。你说你知道如何使它异步,你的问题是“我如何使它异步?”你已经知道了。让它异步!如果您的问题是“我使其异步,但我不想同步等待结果,如何?”则删除同步等待。如果您的问题是“我使其异步,但我不想异步等待结果,如何?”则删除异步等待。在异步代码中,如果不进行等待,就不会发生等待。这就是“异步”的意思。但也就是说,删除异步等待是极其危险的。如果异步操作抛出?如果没有任何东西可以异步等待,那么就没有什么东西可以捕获异常!我说“我必须通过Dynamics CRM插件代码(C#)异步调用Azure函数,这很好。但我不想让代码等待Azure函数的响应。我只想完成代码执行并退出”。也就是说,如果我根据提供的文档转换代码,代码执行仍然挂起并等待web API的响应(本例中为Azure函数)。我只是不想让代码等待这个响应。我想强制代码立即退出。我觉得你在问一个关于你没有发布的代码的问题。很难对我们看不到的代码提出建议。我被这个问题弄糊涂了。你说你知道如何使它异步,你的问题是“我如何使它异步?”你已经知道了。让它异步!如果您的问题是“我使其异步,但我不想同步等待结果,如何?”则删除同步等待。如果您的问题是“我使其异步,但我不想异步等待结果,如何?”则删除异步等待。在异步代码中,如果不进行等待,就不会发生等待。这就是“异步”的意思。但也就是说,删除异步等待是极其危险的。如果异步操作抛出?如果没有任何东西可以异步等待,那么就没有什么东西可以捕获异常!我说“我必须通过Dynamics CRM插件代码(C#)异步调用Azure函数,这很好。但我不想让代码等待Azure函数的响应。我只想完成代码执行并退出”。也就是说,如果我根据提供的文档转换代码,代码执行仍然挂起并等待web API的响应(本例中为Azure函数)。我只是不想让代码等待这个响应。我想强制代码立即退出。我觉得你在问一个关于你没有发布的代码的问题。很难对我们可以使用的代码提出建议
public class CallAzureFunc : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // Extract the tracing service for use in debugging sandboxed plug-ins.  
        ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

        // Obtain the execution context from the service provider.  
        IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext));

        // The InputParameters collection contains all the data passed in the message request.  
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            // Obtain the target entity from the input parameters.  
            Entity entity = (Entity)context.InputParameters["Target"];

            // Verify that the target entity represents an entity type you are expecting.   
            if (entity.LogicalName != "account")
                return;

            // Obtain the organization service reference which you will need web service calls.  
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            try
            {
                // Plug-in business logic goes here.  

                Data data = new Data
                {
                    name = entity.Attributes["name"].ToString()
                };

                string result = CallFunction(tracer, data);
                tracer.Trace($@"result: {result}");
            }

            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex);
            }

            catch (Exception ex)
            {
                tracer.Trace("MyPlugin: {0}", ex.ToString());
                throw;
            }
        }
    }

    private string CallFunction(ITracingService tracer, Data data)
    {
        string json = JsonConvert.SerializeObject(data);

        string apiUrl = "https://<AzureFunctionName>.azurewebsites.net/api/";
        string token = "<token>";
        string content = null;
        string apiMethod = "CreateContactFromLead";
        string inputJson = json;
        string result = ApiHelper.ExecuteApiRequest(apiUrl, token, content, apiMethod, inputJson, tracer);
        return result;
    }
}
    internal static string ExecuteApiRequest(string apiUrl, string token, string content, string apiMethod, string inputJson, ITracingService tracer)
    {
        try
        {
            var data = Encoding.ASCII.GetBytes(inputJson);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format(apiUrl + apiMethod));
            request.Method = "POST";
            request.ContentLength = inputJson.Length;
            request.ContentType = "application/json";
            request.ContentLength = data.Length;
            request.Headers.Add("x-functions-key", token);
            request.Accept = "application/json";

            // Send the data
            Stream newStream = request.GetRequestStream();
            newStream.Write(data, 0, data.Length);
            newStream.Close();

            // Get the resposne
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response != null)
            {
                tracer.Trace("ApiHelper > ExecuteApiRequest > response.StatusCode: " + response.StatusCode);
                tracer.Trace("ApiHelper > ExecuteApiRequest > response.StatusDescription: " + response.StatusDescription);
            }

            if (response.StatusCode == HttpStatusCode.OK || response.StatusDescription == "OK" || response.StatusDescription == "200")
            {
                content = ReadStream(response, tracer);
            }
            else if (response.StatusCode == HttpStatusCode.NoContent || response.StatusDescription == "No Content" || response.StatusDescription == "204")
            {
                content = null;
            }
            else
            {
                if (response != null)
                {
                    throw new Exception(String.Format("Status Code: {0}, Status Description: {1}",
                        response.StatusCode,
                        response.StatusDescription));
                }
            }

            return content;
        }
        catch (Exception ex)
        {
            tracer.Trace("ApiHelper > ExecuteApiRequest > error: " + ex.Message);
            throw;
        }
    }

    private static string ReadStream(HttpWebResponse response, ITracingService tracer)
    {
        try
        {
            var responseJson = string.Empty;
            if (response != null)
            {
                Stream dataStream = response.GetResponseStream();
                if (dataStream != null)
                {
                    using (StreamReader reader = new StreamReader(dataStream))
                    {
                        while (!reader.EndOfStream)
                        {
                            responseJson = reader.ReadToEnd();
                        }
                    }
                }
            }
            return responseJson;
        }
        catch (Exception ex)
        {
            tracer.Trace("ApiHelper > ReadStream > error: " + ex.Message);
            throw ex;
        }
    }
[FunctionName("ServiceBusQueueTriggerCSharp")]                    
public static void Run(
    [ServiceBusTrigger("myqueue", AccessRights.Manage, Connection = "ServiceBusConnection")] 
    string myQueueItem,
    Int32 deliveryCount,
    DateTime enqueuedTimeUtc,
    string messageId,
    TraceWriter log)
{
    log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
    log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
    log.Info($"DeliveryCount={deliveryCount}");
    log.Info($"MessageId={messageId}");
}