Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.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# 在web服务中使用Task.WhenAny()_C#_Web Services_Asynchronous_Task Parallel Library_Async Await - Fatal编程技术网

C# 在web服务中使用Task.WhenAny()

C# 在web服务中使用Task.WhenAny(),c#,web-services,asynchronous,task-parallel-library,async-await,C#,Web Services,Asynchronous,Task Parallel Library,Async Await,我有一个web服务,需要尽快返回数据。我可以查询两个来源。我想返回使用Task.whenny()查询这些源并返回首先返回的项。当我在本地开发环境中运行代码时,代码将成功地从最快的任务返回数据,但当较慢的任务返回时,它会导致IIS Express工作进程崩溃,并出现空引用异常 MyService.asmx <%@ WebService Language="C#" CodeBehind="MyService.asmx.cs" Class="MyWebService.MyService" %&g

我有一个web服务,需要尽快返回数据。我可以查询两个来源。我想返回使用
Task.whenny()
查询这些源并返回首先返回的项。当我在本地开发环境中运行代码时,代码将成功地从最快的任务返回数据,但当较慢的任务返回时,它会导致IIS Express工作进程崩溃,并出现空引用异常

MyService.asmx

<%@ WebService Language="C#" CodeBehind="MyService.asmx.cs" Class="MyWebService.MyService" %>

MyService.asmx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace MyWebService
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class MyService : System.Web.Services.WebService
    {
        private WebCore _webService;

        public MyService()
        {
            _webService = new WebCore();
        }


        [WebMethod]
        public int TestAsync()
        {
            return _webService.TestInt();
        }

    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.Services;
命名空间MyWebService
{
/// 
///服务1的摘要说明
/// 
[WebService(命名空间=”http://tempuri.org/")]
[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
//要允许使用ASP.NET AJAX从脚本调用此Web服务,请取消注释以下行。
//[System.Web.Script.Services.ScriptService]
公共类MyService:System.Web.Services.WebService
{
私人网络中心(webService),;
公共MyService()
{
_webService=newwebcore();
}
[网络方法]
公共int TestAsync()
{
return_webService.TestInt();
}
}
}
WebCore.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Threading.Tasks;

namespace MyWebService
{
   public class WebCore {

       public WebCore() {}

        public int TestInt()
        {
            return AsyncCaller().Result;
        }
        private CancellationTokenSource cts;

        async Task<int> CallOne(CancellationToken ct)
        {
            await Task.Delay(4000);
            return 1;
        }
        async Task<int> CallTwo(CancellationToken ct)
        {
            await Task.Delay(1000);
            return 2;
        }
        private async Task<int> AsyncCaller()
        {
            cts = new CancellationTokenSource();
            var tasks = new List<Task<int>>()
            {
                CallOne(cts.Token),
                CallTwo(cts.Token)
            };

            var completedtasks = await Task.WhenAny(tasks);
            var res = await completedtasks;
            cts.Cancel();
            return res;
        }
   }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用系统线程;
使用System.Threading.Tasks;
命名空间MyWebService
{
公共类网络中心{
公共WebCore(){}
公共int测试()
{
返回AsyncCaller().Result;
}
私有取消令牌源cts;
异步任务CallOne(CancellationToken ct)
{
等待任务。延迟(4000);
返回1;
}
异步任务调用二(CancellationToken ct)
{
等待任务。延迟(1000);
返回2;
}
专用异步任务AsyncCaller()
{
cts=新的CancellationTokenSource();
var tasks=新列表()
{
CallOne(cts.Token),
CallTwo(cts.Token)
};
var completedtasks=wait Task.wheny(任务);
var res=等待完成的任务;
cts.Cancel();
返回res;
}
}
}
在调试模式下执行此操作并运行web服务时,web服务将按预期返回“2”。但是,3秒钟后,当CallOne()完成时,我的应用程序崩溃,出现“调用堆栈仅包含外部代码”和空引用异常“对象引用未设置为对象的实例”。我的堆栈跟踪是:

 at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
   at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
   at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
   at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.Tasks.AwaitTaskContinuation.<ThrowAsyncIfNecessary>b__1(Object s)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
位于System.Web.ThreadContext.AssociateWithCurrentThread(布尔setImpersonationContext)
位于System.Web.HttpApplication.OnThreadEnterPrivate(布尔setImpersonationContext)
位于System.Web.LegacyAspNetSynchronizationContext.CallbackPossiblyUnderlock(SendOrPostCallback回调,对象状态)
位于System.Web.LegacySpNetSynchronizationContext.CallCallback(SendOrPostCallback回调,对象状态)
位于System.Web.LegacySpNetSynchronizationContext.Post(SendOrPostCallback,对象状态)
位于System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(对象状态)
位于System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback回调、对象状态、任务和当前任务)
---来自引发异常的上一个位置的堆栈结束跟踪---
在System.Threading.Tasks.AwaitTaskContinuation.b__1(对象s)中
位于System.Threading.QueueUserWorkItemCallback.WaitCallback_上下文(对象状态)
位于System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext、ContextCallback回调、对象状态、布尔值preserveSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔保存SyncCTX)
位于System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()处
在System.Threading.ThreadPoolWorkQueue.Dispatch()中
在System.Threading.\u ThreadPoolWaitCallback.PerformWaitCallback()中

首先,您需要在ASP.NET中正确启用
异步
/
等待
。为此,请确保您的目标是.NET 4.5,然后

接下来,在完成
async
方法时,您希望避免重新进入请求上下文:

async Task<int> CallOne(CancellationToken ct)
{
    await Task.Delay(4000).ConfigureAwait(false);
    return 1;
}
async Task<int> CallTwo(CancellationToken ct)
{
    await Task.Delay(1000).ConfigureAwait(false);
    return 2;
}
异步任务调用(CancellationToken ct) { 等待任务。延迟(4000)。配置等待(false); 返回1; } 异步任务调用二(CancellationToken ct) { 等待任务。延迟(1000)。配置等待(false); 返回2; }
修改代码以包含所有已接受的文件。添加ConfigureAwait(false)成功了。我猜在默认情况下,较慢任务的执行返回到已经完成的主线程?非常感谢!它正在返回一个已经完成的请求上下文(不是“主线程”),是的。另外,请确保设置
targetFramework