繁体   English   中英

C# HttpWebRequest ,触发并忘记 API 调用

[英]C # HttpWebRequest , Fire and forget an API call

在我的 WCF 服务中,我必须调用一个 API,我想在其中执行 Fire and Forget 实现。 如果可能的话,只捕获错误(如果不是一个选项,那也很好)

我打算做以下实现,它可能导致什么问题? 通过执行以下实现将留下大量打开的连接。 或者可能是什么问题? 请帮助理解如何以更好的方式实现这一点。

void SendRequest(inputs)
 {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
        request.Method = "POST";
        request.ContentType = "application/xml";

        byte[] requestBytes = Encoding.UTF8.GetBytes(inputXML);
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(requestBytes, 0, requestBytes.Length);
        }

        request.GetResponseAsync();
 } 
 Main()
   { 
       try
          SendRequest(inputs);
       catch ex
          log ex;
   }

请注意,不使用即发即弃并不是最佳实践,特别是如果这是应用程序的核心层并且您可能会错过重要的异常。 当您使用此技术时,您必须记住会发生以下情况:

  1. 异常将无声无息地失败,而没有任何机会捕捉到它们。 通常你会想要记录它们或收到通知。
  2. 你不知道代码什么时候完成,
  3. 由于您不需要完成代码并且它可能无法运行,因此您不会收到它无法完成的通知。

使用此技术的一个很好的案例场景可能是更新缓存的示例。

话虽如此,您可以使用以下技术:

NET 4.5 允许我们通过Task.Run使用它

Task.Run(() => FireAndForget());

您还可以使用无参数 lambda 启动线程:

(new Thread(() => { 
 FireAndForget(); 
 }) { 
   Name = "Running Work Thread (FireAndForget)",
   Priority = ThreadPriority.BelowNormal 
}).Start();

首先,制作代码的完全异步版本

public async Task<System.Net.WebResponse> SendRequestAsync(string inputXML, string url)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/xml";

    byte[] requestBytes = Encoding.UTF8.GetBytes(inputXML);
    using (Stream requestStream = await request.GetRequestStreamAsync())
    {
        await requestStream.WriteAsync(requestBytes, 0, requestBytes.Length);
    }

    return await request.GetResponseAsync();
} 

让我们创建一个async void方法,但要使其安全。 它将基本上以“即发即忘”的方式执行。

public async void DoWork(string inputXML, string url)
{
    try
    {
        using(var response = await SendRequestAsync(inputXML, url))
        {
            var httpResponse = (HttpWebResponse) response;
            // Use 201 Created or whatever you need
            if (httpResponse.StatusCode != HttpStatusCode.Created)
            { 
                // TODO: handle wrong status code
            }
        }
    }
    catch (Exception e)
    {
        // TODO: handle exception
    }
}

public static void Main (string[] args)
{
    DoWork("xml string", "example.com");
    Console.WriteLine("Boom!");
}

处理DoWork内部的所有错误很重要,因为以下将不起作用

// Warning, will NOT catch an exception
public static void Main (string[] args)
{
    try 
    {
        DoWork("xml string", "example.com"); 
    }
    catch (Exception e)
    {
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM