相关疑难解决方法(0)

在C#中执行fire and forget方法的最简单方法是什么?

我在WCF中看到他们有[OperationContract(IsOneWay = true)]属性.但是WCF似乎有点缓慢而且很重要,只是为了创建一个非阻塞功能.理想情况下会出现类似静态无效的阻塞MethodFoo(){},但我认为不存在.

在C#中创建非阻塞方法调用的最快方法是什么?

例如

class Foo
{
    static void Main()
    {
        FireAway(); //No callback, just go away
        Console.WriteLine("Happens immediately");
    }

    static void FireAway()
    {
        System.Threading.Thread.Sleep(5000);
        Console.WriteLine("5 seconds later");
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:阅读此内容的每个人都应该考虑他们是否真的想要完成这个方法.(参见#2最佳答案)如果方法必须完成,那么在某些地方,比如ASP.NET应用程序,你需要做一些事情来阻止并保持线程活着.否则,这可能会导致"忘记但永远不会实际执行",在这种情况下,当然,根本不编写任何代码会更简单.(很好地描述了它在ASP.NET中的工作原理)

.net c# nonblocking

134
推荐指数
9
解决办法
8万
查看次数

在asp.net mvc中点火并忘记异步方法

一般的答案,如这里这里发射后不管的问题是不使用异步/ AWAIT,但使用Task.RunTaskFactory.StartNew在同步方式传递来代替.
但是,有时我想要发射并忘记的方法是异步的,并且没有等效的同步方法.

更新注释/警告:正如Stephen Cleary在下面指出的那样,在您发送响应后继续处理请求是危险的.原因是AppDomain可能会在该工作仍在进行时关闭.有关详细信息,请参阅其响应中的链接.无论如何,我只是想提前指出,所以我不会让任何人走错路.

我认为我的情况是有效的,因为实际工作是由不同的系统(不同服务器上的不同计算机)完成的,所以我只需要知道该消息已经留给该系统.如果存在异常,则服务器或用户无法对其进行任何操作并且不会影响用户,我需要做的就是参考异常日志并手动清理(或实现一些自动机制).如果关闭AppDomain,我将在远程系统中有一个残留文件,但是我将在常规维护周期中选择它,因为我的Web服务器(数据库)不再知道它的存在,并且它的名称是唯一的时间戳,它仍然会徘徊不会导致任何问题.

如果我能像Stephen Cleary所指出的那样访问持久性机制,那将是理想的,但不幸的是我现在还没有.

我认为只是假装DeleteFoo请求在客户端(javascript)已经完成,同时保持请求打开,但我需要响应中的信息继续,所以它会保持原状.

那么,原来的问题......

例如:

//External library
public async Task DeleteFooAsync();
Run Code Online (Sandbox Code Playgroud)

在我的asp.net mvc代码中,我想以一种即发即忘的方式调用DeleteFooAsync - 我不想阻止等待DeleteFooAsync完成的响应.如果DeleteFooAsync由于某种原因失败(或抛出异常),则用户或程序无法对其进行任何操作,因此我只想记录错误.

现在,我知道任何异常都会导致未观察到的异常,所以我能想到的最简单的情况是:

//In my code
Task deleteTask = DeleteFooAsync()

//In my App_Start
TaskScheduler.UnobservedTaskException += ( sender, e ) =>
{
    m_log.Debug( "Unobserved exception! This exception would have been unobserved: {0}", e.Exception );
    e.SetObserved();
};
Run Code Online (Sandbox Code Playgroud)

这样做有风险吗?

我能想到的另一个选择是制作我自己的包装器,例如:

private void async DeleteFooWrapperAsync()
{
    try
    {
        await DeleteFooAsync();
    }
    catch(Exception …
Run Code Online (Sandbox Code Playgroud)

.net c# asp.net asynchronous async-await

52
推荐指数
3
解决办法
4万
查看次数

在ASP.NET Core上实现"Fire and Forget"方法的安全方法

我正在尝试实现一个简单的日志库,它将用于多个项目.库的工作是将HTTP请求发送到ElasticSearch.这个库的要点是它不能等待响应.另外,我不关心任何错误/异常.它必须将请求发送到ElasticSearch,并立即返回.我不想用返回类型创建接口Task,我希望它们留下来void.

以下是我的示例代码.这是"火与忘"的正确和安全的实施吗?如果我Task.Run()在高负载库中使用它可以吗?或者我应该避免Task.Run()在我的情况下使用?另外,如果我不使用awaitTask.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)

c# asynchronous task async-await asp.net-core

7
推荐指数
1
解决办法
2299
查看次数

如何在异步方法中启动未等待的后台任务?

我正在努力学习如何在异步方法的世界中执行一些非常长时间运行的后台处理.

使用Stephen Cleary的博客中的词汇,我有兴趣在"承诺任务" 之后启动 "委托await任务".我希望尽快返回承诺的值,并让委托任务在后台继续.

为了处理uned await-ed委托任务中的异常,我将使用在此处描述的模型之后建模的异常处理延续.

public async Task<int> ComplexProcessAsync()
{
  ...
  int firstResult = await FirstStepAsync();

  // THE COMPILER DOESN'T LIKE THIS
  Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult)).LogExceptions();

  return firstResult;
}
Run Code Online (Sandbox Code Playgroud)

因为VeryLongSecondStep...()可能需要很多分钟,并且其结果纯粹是通过副作用(例如出现在数据库中的记录)可观察到的,所以我不愿意这样做await.

但正如所指出的,编译器并不喜欢这样.它警告说"Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call."

我可以忽略这个警告,但我觉得我不是以"正确"的方式做这件事.那么,什么是 …

.net c# async-await

4
推荐指数
1
解决办法
2871
查看次数

当我不需要结果时,是否应该等待异步 SaveToDb 方法?

是否建议等待“_teamRepository.AddTeamToDbAsync(teamToAdd)”方法?它只是为了保存到数据库,无需进一步验证等。如果我不等待保存操作,我会提供更快的结果,但是否存在一些我不知道的风险?

public async Task<OperationResult<TeamDto>> AddTeamAsync(TeamForCreationDto team)
        {
            var teamToAdd = _mapper.Map<Team>(team);
            bool IsNameTaken = await CheckIfTeamExistsAsync(team.Name);

            if (IsNameTaken)
            {
                return new OperationResult<TeamDto>
                {
                    IsSuccess = false,
                    ErrorMessage = "Provided name is already taken.",
                    HttpResponseCode = 409
                };
            }
            else
            {
                _teamRepository.AddTeamToDbAsync(teamToAdd);          // HERE
                var teamToReturn = _mapper.Map<TeamDto>(teamToAdd);
                return new OperationResult<TeamDto>
                {
                    IsSuccess = true,
                    Data = teamToReturn,
                    HttpResponseCode = 201
                };
            }
        }
Run Code Online (Sandbox Code Playgroud)

让我知道你的想法以及我的理解是否正确

c# asynchronous async-await asp.net-web-api asp.net-core

0
推荐指数
1
解决办法
52
查看次数