繁体   English   中英

C# Webservice:调用异步方法的 Webmethod,返回 Taskoff 对象

[英]C# Webservice: Webmethod, that calls an async method, returns Taskoff object

我是网络服务的初学者,我遇到了以下问题,这是关于网络服务和异步日志记录的。 (C#)

问题描述

我有一个 Web 服务,可以将一些数据返回给客户端(asp.net 网站)。

[WebMethod]
public MyClass getData()
{
    //Do some work
    return _myClassObject;
}

到目前为止,这很好用。

因为我想知道 webservice 发布后发生了什么,所以我尝试实现一些简单的日志记录。

以下类(简化)处理日志记录:

public static class Logwriter
{
   public static void writeToLog(string txt)
   {
       //writes log to db
   }
}

我希望这异步发生,所以它不会减慢网络服务的速度。

因此我改变了 WebMethod:

[WebMethod]
public async Task<MyClass> getData()
{
    await Task.Run(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
    //Do some work
    return _myClassObject;
}

在我的 asp.net 网站上更新 ServiceReference 后,我注意到网络服务器不再返回“MyClass”-Object,而是“TaskOffCustomClass”-Object。 我还没有找到从“TaskOffMyClass”-Object 中获取“MyClass”-Object 的解决方案。

问题

  1. 如何从“TaskOffMyClass”获取我的“MyClass”对象?

  2. 是否有可能进行异步日志记录并仍然返回“MyClass”-Object? (使用任务时)

  3. 我想过在线程中进行日志记录,但我也读到建议使用 Task over Thread。 切换到 Thread 的影响有多大?

我是网络服务的初学者

我建议你学习一个现代框架。 我什至不知道 ASMX 现在有多老了……根据我所能找到的,它“没有死”,但我认为这与 Silverlight 是同一种“没有死”。 换句话说,它已经死了,但他们不想正式说它已经死了。

特别是,我认为 ASMX 根本不理解async或任务。 强烈建议学习 ASP.NET WebAPI(如果你真的想要 SOAP,或者 WCF)。

但是,如果您有需要维护的现有 Web 方法,那么...

首先要意识到 - 正如Crowcoder 指出的那样- 你可能不想做一劳永逸的事情。 如果它运行得足够好,那么就保持这样:

[WebMethod]
public MyClass getData()
{
  Logwriter.writeToLog("Someone requested the WebMethod 'GetData'");
  //Do some work
  return _myClassObject;
}

如果您认识到并接受未受保护的后台操作的缺点(特别是,它们可以被中止而您无法检测到,这意味着您的日志可能会丢失一些消息),那么您可以使用类似HostingEnvironment.QueueBackgroundWorkItem东西:

[WebMethod]
public MyClass getData()
{
  HostingEnvironment.QueueBackgroundWorkItem(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
  //Do some work
  return _myClassObject;
}

我在我的博客上描述了替代方法

你在这里很混乱。 希望 Stephen Cleary 也会回答,但您永远不应该在 ASP.Net 中使用Task.Run() 您将使writeToLog异步。 至于返回 Task,@Rene 有一些很好的建议,但也不要在 ASP.Net 中使用.Result ,因为可能会出现死锁。 像日志记录这样的即发即弃操作是非常复杂的 . 您最好将日志发送到队列进行处理。

你可以使用

MyClass result = await service.getData();

或者

Task<MyClass> task = service.getData();
MyClass result = task.Result;

在第一个版本中,您的方法会立即返回给调用者,并在getData完成时在await语句之后恢复。
在第二个版本中,对task.Result的调用会阻止执行,直到Task完成。

暂无
暂无

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

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