Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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# 在任务中进行异步/等待db调用?_C#_Wcf_Asynchronous_Task Parallel Library_Async Await - Fatal编程技术网

C# 在任务中进行异步/等待db调用?

C# 在任务中进行异步/等待db调用?,c#,wcf,asynchronous,task-parallel-library,async-await,C#,Wcf,Asynchronous,Task Parallel Library,Async Await,我们有一个WCF服务,它以以下方式处理传入消息: public bool ProcessMessage(string message) { var returnValue = GetReturnValue(); Task.Run(() => { //do some things with the message UpdateDatabase(); SendRepliesOverNetwork(); });

我们有一个WCF服务,它以以下方式处理传入消息:

public bool ProcessMessage(string message)
{
    var returnValue = GetReturnValue();

    Task.Run(() => {
        //do some things with the message
        UpdateDatabase();
        SendRepliesOverNetwork();
    });

    return returnValue;
}
为了处理尽可能多的消息,我们在这里添加了任务。我们希望尽快将returnValue返回给调用者,并让任务完成它的任务

我的问题:使用可等待的异步数据库调用和/或使用异步方法通过网络进行回复有什么好处吗?


我很谨慎,因为我认为这可能会造成太多的上下文切换。我们已经看到该应用程序使用了100多个线程。首先,我建议你退后一步,真正问问提前返回是否是个好主意。你所做的通常是危险的;在进行实际处理之前,您将向客户机返回“OK”。只有当您的客户知道“returnValue”并不意味着操作已完成,并且只有在收到“SendReplies”后才认为操作已完成时,这才是一个好主意

也就是说,是的,您应该看到尽可能使一切异步化的好处。如果您的所有任务都是非阻塞的,那么您可以更好地利用线程池(减少上下文切换)


我可以看到这种方法存在一些潜在的问题

首先,如果您在IIS中托管WCF服务,那么使用比请求寿命更长的后台线程是一个很大的禁忌。当请求完成时,IIS可以自由地拆除整个
AppDomain
,这将中止所有后台工作,并进行极端的预判断

其次,如果现有工作正在增加,WCF将限制请求。使用此模式,您可以快速处理请求,线程池的排队工作量可能会无限增加


您可以尝试使用WCF异步服务方法。这将释放正在等待IO的线程—您的数据库和网络访问—这可以提高吞吐量

这里有一篇关于这种方法的深入文章:


此外,MSDN中还有一个部分:

这实际上取决于应用程序的上下文,是否希望在发送db更新后立即使UI响应,或者您是出于性能考虑才这样做的?我认为您在这里并没有等待任何东西:您正在线程池上排队工作,并立即返回调用方。@KyleC:为了性能。尽可能快地处理尽可能多的消息。@G.Stoynev:你是对的,只需将处理消息所需的所有工作排队即可。我想知道在db/网络访问上使用async/Wait是否会使线程在等待IO完成时可用于其他消息处理。returnValue基本上是一个应用程序级别的ack,用于告诉调用方我们收到了它的消息。因此,在调用生命周期之外进行处理是可以的。我将继续尝试异步db/网络调用。wcf服务是自托管的,所以我认为应该可以。我将研究wcf异步方法。由于该服务是自托管的,它现在成为您的问题,而不是IIS的问题。考虑一下应用关键服务器操作系统安全更新的计划;您需要知道wcf服务不忙的方式。
public bool ProcessMessage(string message)
{
  var returnValue = GetReturnValue();

  Task.Run(async () => {
    //do some things with the message
    await UpdateDatabaseAsync();
    await SendRepliesOverNetworkAsync();
  });

  return returnValue;
}