我试图用一种新的语法替换我的旧的"即发即忘"调用,希望更简单,它似乎在逃避我.这是一个例子
class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}
static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}
static void Main(string[] args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
两种方法都做同样的事情,但是我似乎已经获得了(没有必要EndInvoke和关闭处理,这仍然有点争议)我正在以新的方式失去等待a Task.Yield(),这实际上带来了一个新的问题必须重写所有现有的异步F&F方法只是为了添加一个单行.在性能/清理方面是否有一些无形的收获?
如果我无法修改背景方法,我将如何应用异步?在我看来,没有直接的方法,我将不得不创建一个等待Task.Run()的包装器异步方法?
编辑:我现在看到我可能会错过一个真正的问题.问题是:给定一个同步方法A(),如何使用async/ await以一种即发即忘的方式异步调用它,而不会得到比"旧方式"更复杂的解决方案
我有一个Web API的操作,我需要运行一些任务而忘记这个任务.这就是我的方法现在的组织方式:
public async Task<SomeType> DoSth()
{
await Task.Run(...);
.....
//Do some other work
}
Run Code Online (Sandbox Code Playgroud)
事情是,显然它停在等待线等待它完成后才继续工作.我需要"解雇并忘记"我是否应该在没有任何异步等待的情况下调用Task.Run()?
我正在寻找有关火灾最佳实践的信息并忘记asp.net mvc行动...基本上我想要一个移动客户端来打电话; 服务器启动异步任务; 然后尽快返回移动客户端.
但我想确保,假设没有异常,异步任务将成功完成.显然有几个不同的选择:
我认为任务将是这里的最佳选择,但想从SO获得想法.
编辑:根据已有的一些答案澄清:客户端不需要回复.我希望一旦服务器开始异步任务,HTTP请求就会尽快完成.我知道客户端上的异步模式,但是我想限制移动设备维持连接打开所需的时间.此外,希望避免有一个单独的进程轮询或推送消息(通过队列,总线等),因为这是过度的.我只想在数据库中记录某些内容,在IO完成之前,客户端不需要保持连接.
我正在尝试实现一个简单的日志库,它将用于多个项目.库的工作是将HTTP请求发送到ElasticSearch.这个库的要点是它不能等待响应.另外,我不关心任何错误/异常.它必须将请求发送到ElasticSearch,并立即返回.我不想用返回类型创建接口Task,我希望它们留下来void.
以下是我的示例代码.这是"火与忘"的正确和安全的实施吗?如果我Task.Run()在高负载库中使用它可以吗?或者我应该避免Task.Run()在我的情况下使用?另外,如果我不使用await带Task.Run(),将我阻塞线程?此代码在库中:
public enum LogLevel
{
Trace = 1,
Debug = 2,
Info = 3,
Warn = 4,
Error = 5,
Fatal = 6
}
public interface ILogger
{
void Info(string action, string message);
}
public class Logger : ILogger
{
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler { Proxy = null, UseProxy = false });
private static IConfigurationRoot _configuration;
public Logger(IConfigurationRoot configuration)
{
_configuration = …Run Code Online (Sandbox Code Playgroud) 我有一个 ASP.Net 应用程序,其中一个后台任务使用HostingEnvironment.QueueBackgroundWorkItem运行,如下面的代码所示。
问题:下面代码中调度的后台任务是使用来自 ASP.Net 线程池线程的线程,还是使用来自单独线程池的线程?
public ActionResult SendCustMails()
{
HostingEnvironment.QueueBackgroundWorkItem(ct => SendCustMailsTo(ct, "Customer Notification"));
return View();
}
private void SendCustMailsTo (CancellationToken ct, string msg)
{
//some code is omitted
foreach (var customer in Customers)
{
if (ct.IsCancellationRequested)
{
break;
}
SendMail(customer, msg);
}
return ct;
}
Run Code Online (Sandbox Code Playgroud) 我正在研究ASP.NET MVC项目.
我需要一些时间来解释我的疯狂情况.
我正在尝试从MVC项目向Android和Apple设备发送推送通知.
两者的发送逻辑都是正确的,请不要浪费你的时间考虑这个
我面临的灾难是:不调用负责发送通知的静态类中的静态方法.(我不是新鲜的程序员,我在C#编程方面有超过5年的时间)但我无法调用方法.
为了让您进入问题的上下文,当我在本地计算机(开发计算机)上执行代码时,将调用并执行此方法并将通知到达设备.
当我发布MVC项目并将其部署到我们的服务器时,不会调用静态方法.
我如何知道该方法未被调用?
因为我正在记录到一个文本文件,并且在调用该方法之前在方法的第一行和一个日志语句中放了一个日志语句.
调用方法之前的日志被执行并充实到文本文件,但是不执行静态方法开始的日志!!!!!.
这是一些代码,然后我会告诉你我试图解决这个问题.
public interface IHandler<T> where T : IMessage
{
Task Handle(T args);
}
public class RequestAddedAppMonitorHandler : IHandler<RequestAdded>
{
public Task Handle(RequestAdded args)
{
return Task.Factory.StartNew(() =>
{
try
{
GoogleNotification notification = CreateAndroidPartnerAppNotification(deviceId);
// this statment is executed, and the text log file will contains this line
TracingSystem.TraceInformation("Before Send Google Notification");
SendersFacade.PartnerSender.Send(notification).Wait();
}
catch (Exception ex)
{
TracingSystem.TraceException(ex);
}
}); …Run Code Online (Sandbox Code Playgroud) 我有Web API方法调用另一个标记为async的方法来更新数据库(使用EF 6).我不需要等待db方法来完成(它的火和忘记),因此我await在调用这个异步方法时不会使用它.如果我不调用await,则抛出NullReferenceException,它永远不会传递给我的代码,只是在VS2013的输出窗口中显示为第一次机会异常.
没有await-ing 处理异步方法的正确方法是什么?
以下是我正在做的事情的一个例子:
数据回购方法:
public async Task UpdateSessionCheckAsync(int sessionId, DateTime time)
{
using (MyEntities context = new MyEntities())
{
var session = await context.Sessions.FindAsync(sessionId);
if (session != null)
session.LastCheck = time;
await context.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
Web api存储库方法:
public async Task<ISession> GetSessionInfoAsync(int accountId, int siteId, int visitorId, int sessionId)
{
//some type of validation
var session =await GetValidSession(accountId, siteId, visitorId, sessionId);
DataAdapter.UpdateSessionCheckAsync(sessionId, DateTime.UtcNow); // this is the line causing the exception if …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
static async Task Callee()
{
await Task.Delay(1000);
}
static async Task Caller()
{
Callee(); // #1 fire and forget
await Callee(); // #2 >1s
Task.Run(() => Callee()); // #3 fire and forget
await Task.Run(() => Callee()); // #4 >1s
Task.Run(async () => await Callee()); // #5 fire and forget
await Task.Run(async () => await Callee()); // #6 >1s
}
static void Main(string[] args)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
Caller().Wait();
stopWatch.Stop();
Console.WriteLine($"Elapsed: {stopWatch.ElapsedMilliseconds}");
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
#1以最简单的方式点火和忘记.#2只是等待.有趣的东西从#3开始.这些电话背后的深度逻辑是什么?
我知道在ASP.NET中使用fire'n'forget作为警告的指向这里 …
在开发一些ASP.Net应用程序时,我看到一些空引用问题.例外情况如下:
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
Stack:
at System.Threading.Tasks.AwaitTaskContinuation.<ThrowAsyncIfNecessary>b__1(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Run Code Online (Sandbox Code Playgroud)
在搜索了Google和SO之后,很可能是由于我的一些代码触发并以这种方式忘记了异步任务:
public interface IRepeatedTaskRunner
{
Task Start();
void Pause();
}
public class RepeatedTaskRunner : IRepeatedTaskRunner
{
public async Task Start() //this is returning Task
{
...
}
}
public class RepeatedTaskRunnerManager{
private IRepeatedTaskRunner _runner;
public void Foo(){
_runner.Start(); //this is not awaited.
}
}
Run Code Online (Sandbox Code Playgroud)
我认为它非常类似于这个问题"在asp.net mvc中消防并忘记异步方法",但并不完全相同,因为我的代码不在控制器上并接受请求.我的代码专门用于运行后台任务.
正如在上面的SO问题中一样,通过将代码更改为下面的问题修复了问题,但我只是想知道为什么以及与从任务返回的异常任务和任务返回的异常有什么区别: …
c# ×7
asynchronous ×5
async-await ×4
asp.net ×2
asp.net-mvc ×2
asp.net-core ×1
c#-5.0 ×1
rest ×1
task ×1