C# 异步\等待方法

C# 异步\等待方法,c#,.net,asynchronous,C#,.net,Asynchronous,我是异步/等待功能的新手,我尝试在我的MVC项目中使用它们 因此,我从控制器调用当前方法来初始化我的模型: var model = this.quantService.GetIndexViewModel(companyIds, isMore, currentrole).Result; 在这个GetIndexViewModel中,我使用了wait: public async Task<CompanyBoardViewModel> GetIndexViewModel(IEnumerab

我是异步/等待功能的新手,我尝试在我的MVC项目中使用它们

因此,我从控制器调用当前方法来初始化我的模型:

var model = this.quantService.GetIndexViewModel(companyIds, isMore, currentrole).Result;
在这个GetIndexViewModel中,我使用了
wait

public async Task<CompanyBoardViewModel> GetIndexViewModel(IEnumerable<int> parameter, bool isMore = false, bool currentRole = false)
        {
                return new CompanyBoardViewModel
                {
                    TopJoinAplicant = await this.TopJointApplicant(parameter, isMore),
                    TopPriorityCountry = await this.TopPriorityCountry(parameter),
                    TopPublicationCountries = await this.TopPublicationCountries(parameter),
                    TopGrantedInventors = await this.TopGrantedInventors(parameter),
                    TopIPC = await this.TopIPC(parameter),
                    TopCPC = await this.TopCPC(parameter),
                    TopCitedInventors = await this.TopCitedInventors(parameter),
                    TopCitedPatents = await this.TopCitedPatents(parameter),
                    CGAR = await this.GetCGAR(parameter),
                };

}
public异步任务GetIndexViewModel(IEnumerable参数,bool isMore=false,bool currentRole=false)
{
返回新公司BoardViewModel
{
TopJoinAplicant=等待此操作。TopJointApplicant(参数isMore),
TopPriorityCountry=等待此操作。TopPriorityCountry(参数),
TopPublicationCountries=等待此消息。TopPublicationCountries(参数),
TopGrantedInventors=等待此消息。TopGrantedInventors(参数),
TopIPC=等待此。TopIPC(参数),
TopCPC=等待此参数。TopCPC(参数),
TopCitedInventors=等待此操作。TopCitedInventors(参数),
TopCitedPatents=等待此。TopCitedPatents(参数),
CGAR=wait this.GetCGAR(参数),
};
}
对于第一种方法,我使用以下代码:

private async Task<QuantTableViewModel<TopFilterViewModel>> TopJointApplicant(IEnumerable<int> ids, bool isMore = false)
        {

            return await Task.Run(() => new QuantTableViewModel<TopFilterViewModel>
            {
                Tableid = "TopJointApplicants",
                Title = "Top Joint Applicants",
                FirstCol = "Position",
                SecondCol = "Joint Applicant",
                ThirdCol = "#",
                IsSeeMore = isMore,
                Data = this.cache.TopJointApplicant(ids).ToList()
            });
}
私有异步任务TopJointApplicant(IEnumerable ID,bool isMore=false)
{
返回等待任务。运行(()=>new QuantTableViewModel
{
Tableid=“TopJointApplicants”,
Title=“顶级联合申请人”,
FirstCol=“Position”,
SecondCol=“联合申请人”,
ThirdCol=“#”,
IsSeeMore=isMore,
Data=this.cache.TopJointApplicant(ids).ToList()
});
}
在这个方法中,我调用:
Data=this.cache.topjointaplicant(ids.ToList()
此方法创建了一个过程并从数据库获取信息(该方法执行时没有任何问题),但当我尝试返回
quantableviewmodel
I堆栈时(在死亡日志中)


如果有人知道为什么会发生这种情况,我会非常高兴。

您不需要使用Task.Run,而是使用async/await模式

在这种情况下,我想说的是,您的公共方法是异步的就足够了,因为topjointaplicant中实际上没有任何异步操作

    public async Task<CompanyBoardViewModel> GetIndexViewModel(IEnumerable<int> parameter, bool isMore = false, bool currentRole = false)
        {
                return new CompanyBoardViewModel
                {
                    TopJoinAplicant = this.TopJointApplicant(parameter, isMore),
                    TopPriorityCountry = await this.TopPriorityCountry(parameter),
                    TopPublicationCountries = await this.TopPublicationCountries(parameter),
                    TopGrantedInventors = await this.TopGrantedInventors(parameter),
                    TopIPC = await this.TopIPC(parameter),
                    TopCPC = await this.TopCPC(parameter),
                    TopCitedInventors = await this.TopCitedInventors(parameter),
                    TopCitedPatents = await this.TopCitedPatents(parameter),
                    CGAR = await this.GetCGAR(parameter),
                };
    }

    private QuantTableViewModel<TopFilterViewModel> TopJointApplicant(IEnumerable<int> ids, bool isMore = false)
            {
                var Data = this.cache.TopJointApplicant(ids).ToList();
                return new QuantTableViewModel<TopFilterViewModel>
                {
                    Tableid = "TopJointApplicants",
                    Title = "Top Joint Applicants",
                    FirstCol = "Position",
                    SecondCol = "Joint Applicant",
                    ThirdCol = "#",
                    IsSeeMore = isMore,
                    Data = this.cache.TopJointApplicant(ids).ToList()
                });
            }
}

总而言之。之所以应该使用wait/async,是因为您可以一直执行到执行缓慢的操作(如DB或webservice)。或者如果你想同时做几件事

在您的特定情况下,您可以执行以下操作:

public async Task<CompanyBoardViewModel> GetIndexViewModel(IEnumerable<int> parameter, bool isMore = false, bool currentRole = false)
{
    // Let the threads start processing.
    var topApplicantTask = this.TopJointApplicant(parameter, isMore);
    var topPriorityCountryTask = this.TopPriorityCountry(parameter);
    var topPublicationContriesTask = this.TopPublicationCountries(parameter);
    var topIPCTask = this.TopIPC(parameter);
    var topCPCTask = this.TopCPC(parameter);
    var topCitedInventorsTask = this.TopCitedInventors(parameter);
    var topCitetPatentsTask = this.TopCitedPatents(parameter);
    var getCGARTask = this.GetCGAR(parameter);

    // Await them later.
    return new CompanyBoardViewModel
    {
        TopJoinAplicant = await topApplicantTask,
        TopPriorityCountry = await topPriorityCountryTask,
        TopPublicationCountries = await topPublicationContriesTask,
        TopGrantedInventors = await this.TopGrantedInventors(parameter),
        TopIPC = await topIPCTask,
        TopCPC = await topCPCTask,
        TopCitedInventors = await topCitedInventorsTask,
        TopCitedPatents = await topCitetPatentsTask,
        CGAR = await getCGARTask,
     };
}
public异步任务GetIndexViewModel(IEnumerable参数,bool isMore=false,bool currentRole=false)
{
//让线程开始处理。
var topplicanttask=this.topjointaplicant(参数isMore);
var-topPriorityCountryTask=this.TopPriorityCountry(参数);
var-toppublicationcontriesstask=this.TopPublicationCountries(参数);
var topictask=this.topic(参数);
var topCPCTask=this.topcp(参数);
var topCitedInventorsTask=this.TopCitedInventors(参数);
var topCitetPatentsTask=此.TopCitedPatents(参数);
var getCGARTask=this.GetCGAR(参数);
//等他们回来。
返回新公司BoardViewModel
{
TopJoinAplicant=等待TopAppliantTask,
TopPriority Country=等待TopPriority Country任务,
TopPublicationCountries=等待TopPublicationContrries任务,
TopGrantedInventors=等待此消息。TopGrantedInventors(参数),
TopIPC=等待TopIPC任务,
topcp=等待topCPCTask,
TopCitedInventors=等待topCitedInventorsTask,
TopCitedPatents=等待topCitetPatentsTask,
CGAR=等待GetCGartTask,
};
}

但尽量避免任务。运行,因为它被视为反模式。相反,尝试从控制器到实际操作(DB、IO、webservice)一直使用wait/async。此外,在上面的例子中,有很多线程正在进行。它可能需要清理一点,但您可以将其视为概念证明,而不是建议的解决方案。

您实际上可以拥有一个异步控制器,因此不需要调用.Result,从而使异步操作同步运行

比如:

public Task<ActionResult> Index(object parameter)
{
    var model = await this.quantService.GetIndexViewModel(companyIds, isMore, currentRole);

    return View(model);
}
公共任务索引(对象参数)
{
var model=wait this.quantService.GetIndexViewModel(companyId、isMore、currentRole);
返回视图(模型);
}

我解释了您在我的博客上看到的死锁。简言之相反,使用

但你的方法还有其他问题。正如其他人所指出的,
wait Task.Run
是ASP.NET上的反模式。你可能想读我的文章


最后,还有一个提示:您从错误的方向处理问题。您应该首先考虑应用程序正在做什么,并开始在最低级别将I/O调用转换为异步,而不仅仅是选择一种“使异步”的方法。将它们转换为使用异步API而不是阻塞API(即,no
Task.Run
)。然后将调用者更改为async,将调用者更改为async,最终将控制器方法更改为async。

您能为您的方法提供正确的格式吗?@ÖmerCinbat-我已提交了一份编辑,目前正在等待同行审查。您使用wait+Task.Run是毫无意义的,实际上是有害的。我建议你研究一下异步为什么好,什么时候好。我在没有Task.Run()的情况下尝试过,但是我在没有Task.Run()的情况下得到的时间与我没有使用wait(因此逻辑是如此的不异步)@KostadinPirgov-我不确定你是否完全理解
异步
的作用
wait Task.Run()
是一种反模式,因为您只需将某些活动移动到另一个线程上,然后立即挂起当前线程正在处理的内容,直到结果可用。谢谢,我现在就尝试!我尝试了你的建议,但我收到的时间与我不使用异步的时间相同/
public async Task<CompanyBoardViewModel> GetIndexViewModel(IEnumerable<int> parameter, bool isMore = false, bool currentRole = false)
{
    // Let the threads start processing.
    var topApplicantTask = this.TopJointApplicant(parameter, isMore);
    var topPriorityCountryTask = this.TopPriorityCountry(parameter);
    var topPublicationContriesTask = this.TopPublicationCountries(parameter);
    var topIPCTask = this.TopIPC(parameter);
    var topCPCTask = this.TopCPC(parameter);
    var topCitedInventorsTask = this.TopCitedInventors(parameter);
    var topCitetPatentsTask = this.TopCitedPatents(parameter);
    var getCGARTask = this.GetCGAR(parameter);

    // Await them later.
    return new CompanyBoardViewModel
    {
        TopJoinAplicant = await topApplicantTask,
        TopPriorityCountry = await topPriorityCountryTask,
        TopPublicationCountries = await topPublicationContriesTask,
        TopGrantedInventors = await this.TopGrantedInventors(parameter),
        TopIPC = await topIPCTask,
        TopCPC = await topCPCTask,
        TopCitedInventors = await topCitedInventorsTask,
        TopCitedPatents = await topCitetPatentsTask,
        CGAR = await getCGARTask,
     };
}
public Task<ActionResult> Index(object parameter)
{
    var model = await this.quantService.GetIndexViewModel(companyIds, isMore, currentRole);

    return View(model);
}