我使用基于任务的操作生成了代理.
如何使用async/await 正确调用此服务(处理ServiceClient和OperationContext之后)?
我的第一次尝试是:
public async Task<HomeInfo> GetHomeInfoAsync(DateTime timestamp)
{
using (var helper = new ServiceHelper<ServiceClient, ServiceContract>())
{
return await helper.Proxy.GetHomeInfoAsync(timestamp);
}
}
Run Code Online (Sandbox Code Playgroud)
作为ServiceHelper一个创造ServiceClient和OperationContextScope后来处理它们的类:
try
{
if (_operationContextScope != null)
{
_operationContextScope.Dispose();
}
if (_serviceClient != null)
{
if (_serviceClient.State != CommunicationState.Faulted)
{
_serviceClient.Close();
}
else
{
_serviceClient.Abort();
}
}
}
catch (CommunicationException)
{
_serviceClient.Abort();
}
catch (TimeoutException)
{
_serviceClient.Abort();
}
catch (Exception)
{
_serviceClient.Abort();
throw;
}
finally …Run Code Online (Sandbox Code Playgroud) 我有一个在所有应用程序中使用的值; 我在application_start中设置了它
void Application_Start(object sender, EventArgs e)
{
Dictionary<int, IList<string>> Panels = new Dictionary<int, IList<string>>();
List<clsPanelSetting> setting = clsPanelSettingFactory.GetAll();
foreach (clsPanelSetting panel in setting)
{
Panels.Add(panel.AdminId, new List<string>() { panel.Phone,panel.UserName,panel.Password});
}
Application["Setting"] = Panels;
SmsSchedule we = new SmsSchedule();
we.Run();
}
Run Code Online (Sandbox Code Playgroud)
并在SmsSchedule
public class SmsSchedule : ISchedule
{
public void Run()
{
DateTimeOffset startTime = DateBuilder.FutureDate(2, IntervalUnit.Second);
IJobDetail job = JobBuilder.Create<SmsJob>()
.WithIdentity("job1")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1")
.StartAt(startTime)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(60).RepeatForever())
.Build();
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sc …Run Code Online (Sandbox Code Playgroud) 我有一个使用repository(userRepo)的方法:
public override Task<IdentityResult> CreateLocalUserAsync(IUser user, string password, CancellationToken cancellationToken)
{
var task = new Task<IdentityResult>(() => {
TUserEntity newUser = new TUserEntity
{
Id = user.Id,
UserName = user.UserName,
Password = password
};
userRepo.Save(newUser).Flush();
return new IdentityResult(true);
}, cancellationToken);
task.Start();
return task;
}
Run Code Online (Sandbox Code Playgroud)
该userRepo对象具有使用的依赖项HttpContext.Current.这两个都是使用ninject解决的InRequestScope.
AccountController在Mvc 5中默认调用上面的方法:
var result = await IdentityManager.Users.CreateLocalUserAsync(user, model.Password);
Run Code Online (Sandbox Code Playgroud)
我尝试将此设置添加到web.config:
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
Run Code Online (Sandbox Code Playgroud)
另外,我肯定使用的是.NET 4.5.这也在我的web.config中:
<httpRuntime targetFramework="4.5" />
Run Code Online (Sandbox Code Playgroud)
HttpContext在我开始执行任务之前无法获取信息,因为任务中的依赖userRepo项正在使用信息,并且使用Ninject解析了这两个对象.
我怎样才能确保HttpContext.Current不会为空?
我试图阅读异步方法,现在我正在尝试创建自己的异步方法.该方法是一个webservice调用,它返回错误日志列表.我不确定我是否理解正确,所以我想我会分享我的代码,看看我是否应该做任何不同的事情.
我想要的代码就是通过调用方法GetAllErrorLogs()来返回错误日志列表,这是一个同步方法.因为我需要一秒钟才能获取所有错误日志,所以当我调用GetAllErrorLogs()方法时,我希望有机会做其他事情.这是代码.
[WebMethod]
public async Task<List<ErrorLog>> GetAllErrorLogs()
{
List<ErrorLog> errorLogs = new List<ErrorLog>();
await System.Threading.Tasks.Task.Run(() => {
errorLogs = ErrorLogRepository.GetAllErrorLogs();
});
if (errorLogs == null)
return new List<ErrorLog>();
return errorLogs;
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
我有一个针对.NET 4.6的ASP.NET应用程序,我疯狂地试图找出为什么HttpContext.Current在我的异步MVC控制器操作中第一次等待之后变为null.
我检查并三重检查我的项目是针对v4.6,web.config的targetFramework属性也是4.6.
SynchronizationContext.Current在await之前和之后分配,它是正确的,即AspNetSynchronizationContext不是遗留的.
FWIW,await有问题确实在继续时切换线程,这可能是由于它调用外部I/O绑定代码(异步数据库调用)但这应该不是问题,AFAIU.
然而,它是!HttpContext.Current变为null 的事实导致我的代码出现了许多问题,对我来说没有任何意义.
我检查了通常的建议,我很肯定我正在做我应该做的一切.我的代码中也完全没有ConfigureAwait!
我所拥有的是,我的HttpApplication实例上有几个异步事件处理程序:
public MvcApplication()
{
var helper = new EventHandlerTaskAsyncHelper(Application_PreRequestHandlerExecuteAsync);
AddOnPreRequestHandlerExecuteAsync(helper.BeginEventHandler, helper.EndEventHandler);
helper = new EventHandlerTaskAsyncHelper(Application_PostRequestHandlerExecuteAsync);
AddOnPostRequestHandlerExecuteAsync(helper.BeginEventHandler, helper.EndEventHandler);
}
Run Code Online (Sandbox Code Playgroud)
我需要这两个因为自定义授权和清理逻辑,这需要异步.AFAIU,这是支持的,不应该是一个问题.
还有什么可能是我看到这种令人费解的行为的原因?
更新:补充观察.
SynchronizationContext在等待与等待之前,引用保持不变.但它的内部变化在下面的截图中可以看到!
我不确定这与我的问题有什么关系(或者甚至是否).希望别人能看到它!
我正在尝试在我的 web api 站点上设置 MiniProfiler,并且很难MiniProfiler.Current开始工作。
我按照 miniprofiler.com 上的指示,在 global.asax 中有以下内容:
protected void Application_Start()
{
MiniProfilerEF6.Initialize();
// other setup
}
protected void Application_BeginRequest() {
// need to start one here in order to render out the UI
MiniProfiler.Start();
}
protected void Application_EndRequest() {
MiniProfiler.Stop();
}
Run Code Online (Sandbox Code Playgroud)
这使用默认的WebRequestProfilerProvider,它将实际的配置文件对象存储在HttpContext.Current.Items.
当我要求时MiniProfiler.Current,它看起来像HttpContext.Current。
当我请求我的 Web api URL 之一时:
Application_BeginRequest 创建分析器,将其存储在 HttpContext.CurrentMessageHandler,我可以看到HttpContext.CurrentIActionFilter,HttpContext.Current现在为空,我的尝试MiniProfiler.Current.Step("controller:action")失败了 …我有一个Asp.Net应用程序,它使用由svcutil生成的代理调用一些WCF服务.生成的代理在APM模式(BeginXxx,EndXxx)中具有异步方法.
我正在使用异步定位包以利用新async/await模式,我的目标平台是.net 4.0(否则我不必使用异步定位包).
我正在使用Task<T>.Factory.FromAsync将APM模式转换为我可以等待的任务.
我的代码看起来像那样(假设service方法没有参数并返回一个int:
int result = await Task<int>.Factory.FromAsync(proxy.BeginXxx, proxy.EndXxx, state: null);
HttpContext.Current.Items["reuslt"] = result;
Run Code Online (Sandbox Code Playgroud)
第二行抛出一个NullReferenceException.
我假设原因是回调(这是在await调用之后运行的所有内容)没有原始同步上下文.
其他方法(如Factory.StartNew)具有接收可用于保留上下文的重载TaskScheduler.
FromAsync方法也有重载,接收a TaskScheduler,但没有将begin方法作为参数.
假设我不想开始手动传递Http上下文作为在此行之后调用的所有方法的方法参数,如何使用获取任务调度程序的重载或以其他方式使.Net尊重我的同步上下文?
如果我有一个asyncWeb API 方法,则该Request对象为 null(正如其他帖子(例如这篇文章中讨论的 id ))。
在这种情况下返回响应的最常见方法似乎是使用类似
return new HttpResponseMessage(HttpStatusCode.OK) {
Content = new ObjectContent<T>(myObj, new JsonMediaTypeFormatter())
};
Run Code Online (Sandbox Code Playgroud)
但是格式呢?通常,Request对象会处理该问题,因为它知道请求的内容,但如果我没有对象,Request那么我如何知道请求的格式?
我正在尝试在 asp.net 4.8 中编写异步代码,但问题是从等待返回后 HttpContext 为空。这意味着异步代码可以正常工作,这很好,但是原始代码需要 HttpContext。从下面Darin Dimitrov的回答中的评论可以看出,HttpContext 从 4.6.1 开始就存在这个问题。 为什么 HttpContext.Current 在等待之后为空?
var domains = HttpContext.Current.Cache.Get("domains") as Dictionary<String, Domains>;
if (domains == null)
{
var x = await TrackingMethods.GetTableForCacheAsync().ConfigureAwait(false);
domains = x.domains;
}
/// HttpContext.Current is null here
Run Code Online (Sandbox Code Playgroud) c# ×7
async-await ×5
asp.net ×4
httpcontext ×3
.net ×2
asynchronous ×2
wcf ×2
iis ×1
ninject ×1