【问题标题】:Threading a .Net web service and providing a repsonse before continuing processing在继续处理之前线程化 .Net Web 服务并提供响应
【发布时间】:2014-05-14 21:03:41
【问题描述】:

让我从一个事实开始,这个问题的类似形式在这里被问到,但没有工作示例或可用的主题答案(我已经能够找到)。这篇文章将尝试提供一个更简洁的示例,并为此推进一个代码块。参考以下类似但不是结论性/工作示例的链接。

similar link #1 Background worker

similar link #2 Multi Threading in web service

similar link #3 threading in ASP.net

similar link #4 acknowledge quickly but continue processing

其他链接:

#1 Async Web service Call

#2 Calling Web Service Async functions from web page

#3 MS ThreadPool.QueueUserWorkItem Method

#4 MS Multithreading Walk Through Forms based

问题是向使用 Web 服务的客户端返回响应,以便客户端可以在 Web 服务完成处理任务时继续前进。 Web 服务(身份验证后)从客户端接收文件名,该文件名应从远程 ftp 服务器检索。将文件下载到 Web 服务托管服务器后,即可释放客户端,因为文件名有效并已复制到本地服务器。

Web 服务器在向客户端返回一个简单的“真”布尔响应后,继续将下载的文件压缩到数据库中,并愉快地等待下一个文件的名称。

当前调用是一个 SOAP 消息,这是一个传统的 asmx Web 服务。

网络服务:

<WebService details .....

Public sourceFile As String
Public myData as Boolean = False
    <WebMethod()> _
Public Function fileReady_Log2(ByVal user As String, ByVal PW As String, ByVal fileName As String) As String

    ' This function receives a web service call notifying this server to retrieve a file from a remote ftp server When the file is downloaded it is processed into this servers database.
    '
    ' This routine attempts to process an ASYNC routine to respond to the call and release the caller as soon as possible while continuing processing requirements.

    ' Validation removed for simplicity 
    If authorized Then
    ' Need to retrieve ftp server information and pull down the file and load it to the database.
        ' Call Async function

        sourceFile = filename

        Dim myObject = New ftpThread()
        myObject.SendDataAsync()

        ' Ok, now return the result to client.
        Return myData

        Dim ftpInfo As New ftpFileImport   '  continue with processing the uploaded file.
        results = ftpInfo.retrieveLogFile(fileName, deviceID, usr)


        Return results
    End If
    Return results
End Function

目前这是调用函数的结构。我尝试了多种变体,并决定现在是停下来寻求帮助的好时机。

ftpThread.vb

Imports Microsoft.VisualBasic
Imports System.Threading


Public Class ftpThread
    Public Sub SendDataAsync()
        ThreadPool.QueueUserWorkItem(Sub(getFtpFileExists(sourceFile )))
    End Sub
End Class

我在上面的单词 Sub 上也收到了 Expression Expected 异常。

ftp函数这个过程是同步的,需要异步的。

 Public Class ftpFileExistsCheck
      Public Sub getFtpFileExists()

        ' This all works without ASYNC 

           '  Retrieve FTP credentials from DB
           '  Set up ftp request
           '  download the file.

        '  But continuing process to DB at this point causes client to wait.
           myData  = True
     End Sub
 End Class

我以为我可以从我所阅读的所有内容中弄清楚这一点,但我就是无法为 ASYNC 处理设置正确的编码。

【问题讨论】:

  • ASMX 是一项遗留技术,不应用于新开发。 WCF 或 ASP.NET Web API 应该用于 Web 服务客户端和服务器的所有新开发。一个提示:Microsoft 已停用 MSDN 上的 ASMX Forum
  • @John Saunders 谢谢,我知道遗留技术。由于处理较大文件的延迟,这是对现有服务的增强。寻找快速修复认为线程可以做到这一点。
  • WCF 支持单向消息传递和补偿执行,这正是您想要的。如果可以,请采纳约翰的建议,然后继续。坦率地说,我认为只有肥皂服务器和客户端的自定义实现才能处理您的场景。
  • 另外,最好不要在 Web 服务中执行长时间运行的任务。相反,创建一个单独的服务并将工作排队到单独的服务。您甚至可以使用 WCF 对请求进行排队,其他服务可以自行托管。
  • 长时间运行预计不会超过 1 分钟左右,但在我们的案例中,这对于客户端应用程序来说已经很长了。

标签: vb.net multithreading web-services asynchronous asmx


【解决方案1】:

在您的 ASMX 服务实现中,您应该启动 WCF 客户端并调用单向服务操作,直接传递消息。这不仅可以解决您的问题,而且当您可以从 ASMX 升级时,您可以直接转到新的但仍然熟悉的 WCF 端点。

  1. 实现一个 WCF 服务,它可以反映您需要此类功能的现有 ASMX 方法
  2. 使每个服务操作都成为单向操作
  3. 修改现有的 ASMX 服务以使用新的 WCF 服务并享受

另一种选择是使用 Windows Workflow Foundation (WF)。 WF 允许您使用某些服务调用的结果来补偿活动。这意味着您的服务会继续进行,直到您需要服务中的价值,类似于asyncawait 的工作方式。您可以创建一个代表现有 ASMX 服务的 WCF 工作流服务,并使工作流成为单向服务操作,然后启动整个工作流并将工作流中的工作项出列,直到完成或某个到期时间或您需要指示的任何标准工作流应该停止期待更多的工作。

【讨论】:

  • 你让这听起来很容易。我必须说我真的很想开始更多地研究 WCF 解决方案。我不认为我可以在 WCF 中编写相同的 asmx(镜像)。这行得通吗?
  • 单向操作是否仍会提供某种响应,让客户端知道已收到请求?这是必要的,以便客户端可以从其本地存储中删除上述 ftp 文件。
  • WCF 客户端等待远程服务器关闭连接,如果在发送请求和关闭连接之间没有收到错误,则表示已接受并正在处理。但是,如果您需要这种弹性,您应该使用具有 ACID 事务的服务代理,而不是依赖远程服务器硬件足够稳定以向客户端保证可以删除本地文件。 ACID 事务将确保请求被接收、持久化,并且如果断电或 RAM 掉电,服务器上的所有内容仍然可以恢复。
  • 谢谢迈克尔,我在补偿上找到了这个 MSDN 示例msdn.microsoft.com/en-us/library/vstudio/ms742132(v=vs.90).aspx。此外,关于事务,由于所有处理都发生在同一台服务器上,我不确定是否有可行的解决方案,客户端没有资源参与事务,但我认为可能能够添加第二方服务器.如果文件进入 Web 服务,那么这个简单的解决方案通过简单的布尔响应从客户端触发另一个测试可能更可行。我现在正在处理 WCF 服务部署。
  • @htm11h 我所说的事务是指当你使用服务代理时,它不会告诉客户端它已经接受了请求,直到它可以保证在发生故障时服务是留在承诺状态。它不会等到整个操作完成,而是等到数据持久化到服务器并开始处理。如果没有 ACID 事务,您可能会在关闭连接之前失去网络连接,服务器可能会将其解释为正在中止,而客户端也不会更明智地删除其文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多