1

我对此进行了谷歌搜索,并设法找到了几个链接来解释 C# 和 Web Api 2 中的异步 HTTP 请求的概念。但是我没有得到任何相同的工作示例。

只是为了清除空气,我的要求如下。当客户端调用 API(执行长时间运行的处理)时,它必须几乎立即返回 HTTP 202(已接受)作为响应,并在后台继续处理。到目前为止我很清楚。下面是我如何实现相同的示例代码。我卡住的地方是当这个长时间的处理任务在后台完成时,它必须向同一个客户端触发回调并返回 HTTP 200 响应。可能在后台执行长处理任务时,客户端发出了另一个具有不同值的并发请求。

谁能指出我正确的方向。这是否只能通过代码实现,或者是否有任何设置要在 IIS 级别实现。感谢您在这方面的时间和帮助。

提前感谢大家。

到目前为止我的代码。

public HttpResponseMessage Execute(string plugin, string pluginType, string grid, string version)
    {
        try
        {
            var type = this.LoadPlugin(plugin, pluginType, version);

            if (type != null)
            {
                var method = type.GetMethod("Execute");

                if (method != null)
                {
                    new Task(() =>
                    {
                        // This line will take long to execute.
                        var filepath = method.Invoke(Activator.CreateInstance(type), new object[1] { grid });

                        // After this line it must invoke a callback to the client with the response as "filepath" and HTTP status code as 200 
                        type = null;                            
                    }).Start();
                }
                else
                {
                    return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable);
                }
            }
            else
            {
                return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable);
            }
        }
        catch (Exception ex)
        {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }

        return new HttpResponseMessage(HttpStatusCode.Accepted);
    }

    private Type LoadPlugin(string plugin, string pluginType, string version)
    {
        Assembly assembly;

        Type returnValue = null;

        var pluginFile = new DirectoryInfo(this._pluginPath).GetFiles("*.dll")
                                                            .Where(file => FileVersionInfo.GetVersionInfo(file.FullName).OriginalFilename.ToUpper().Contains("TRANSFORMATION." + plugin.ToUpper()))
                                                            .OrderByDescending(time => time.LastWriteTime).FirstOrDefault();

        if (pluginFile != null)
        {
            assembly = Assembly.LoadFrom(pluginFile.FullName);

            AppDomain.CurrentDomain.Load(assembly.GetName());

            returnValue = assembly.GetType("Transformation.Plugins." + pluginType);

            assembly = null;
        }

        return returnValue;
    }
4

1 回答 1

0

我认为你可以解决这个问题,使你的 Web API 方法异步:

public async Task<HttpResponseMessage> Execute(string plugin, string pluginType, string grid, string version)
{
    // Your code here
}

此外,您的任务调用应该使用 await 关键字,如下所示:

await Task.Run(() =>
{
    // Yor code here
});

您可以在异步方法中有多个等待。

让我知道这个答案是否有用。

于 2016-09-29T05:04:48.737 回答