相关疑难解决方法(0)

使用异步vs"旧异步委托"进行即发即弃

我试图用一种新的语法替换我的旧的"即发即忘"调用,希望更简单,它似乎在逃避我.这是一个例子

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以一种即发即忘的方式异步调用它,而不会得到比"旧方式"更复杂的解决方案

c# asynchronous c#-5.0

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

在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万
查看次数

在没有await关键字的情况下调用async方法究竟发生了什

我有一个Web服务器,并有定期作业合并和发送记录(许多请求日志).

Task.Run(() =>
{
    while (true)
    {
        try
        {
            MergeAndPutRecords();
        }
        catch (Exception ex)
        {
            Logger.Error(ex);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

MergeAndPutRecords函数中,有代码合并记录和异步函数返回任务发送记录.(实际上它是亚马逊Kinesis Firehose的PutRecordBatchAsync.)

如果我在没有await关键字的情况下调用该函数会发生什么?函数是否在单独的线程上运行?这里说它不是.那么什么是返回任务手段?这里说async方法没有等待关键字的意思

  1. 在当前线程上启动异步方法.忽略所有结果(包括例外).

然后同时处理我的定期作业和PutRecordBatchAsync?我知道asynchronouse和concurrent是不同的.但是没有await关键字,它们在同一个线程中.首先执行哪一个?我很困惑......

会有大量记录需要合并并实时发送.所以我认为它必须同时执行..

c# asynchronous async-await

9
推荐指数
1
解决办法
4964
查看次数

不可等待为“即发即忘” - 使用安全吗?

我们需要在我们的代码中写一些日志。
日志是通过记录一些信息的网络请求写入的(记录器是一个 Http-API 模块),但是如果 API 中有异常,我们不想中断整个流程。

我不Task.Run用于这种操作,因为它很糟糕。

但后来我想到了 non-awaitable-inline-function ,像这样:

private static readonly HttpClient client = new HttpClient();

void Main()
{

    Console.WriteLine(1);
    async Task LogMe()
    {
        var response = await client.PostAsync("http://www.NOTEXISTS.com/recepticle.aspx", null);
        var responseString = await response.Content.ReadAsStringAsync();
        //response.EnsureSuccessStatusCode(); // I don't need this here
        Console.WriteLine("error");
    }

    //some code
    LogMe();
    //some code
    Console.WriteLine(3);

}
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
Run Code Online (Sandbox Code Playgroud)

题:

它是登录“即发即忘”模式的可行解决方案吗?
如果我在这个内联方法中创建对象,它们什么时候会被 GC 处理呢?

c# async-await

6
推荐指数
1
解决办法
259
查看次数

为什么 SemaphoreSlim.WaitAsync 不起作用?在 GetAccesTokenAsync 调用完成之前它会跳转到“return currentToken.AccessToken”

SemaphoreSlim.WaitAsync不管用。它跳转到调用完成return currentToken.AccessToken之前并抛出 NullException。GetAccesTokenAsync我也尝试使用 AsyncLock、AsyncSemaphore 和我在网上阅读的其他一些方法,但它似乎对我的情况不起作用。

public static class HttpClientHelper
{
    #region members
    private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
    private static Token currentToken;
    #endregion

    public static string GetAuthorizeToken(ref HttpClient client, string username, string password)
    {
        GetToken(client, username, password);

        return currentToken.AccessToken;
    }

    private static async void GetToken(HttpClient client, string username, string password)
    {
        await semaphore.WaitAsync();

        try
        {
            if (currentToken == null)
            {
                await GetAccesTokenAsync(client, username, password);
            }
            else if (currentToken.IsExpired)
            {
                await GetAccessTokenByRefreshToken(client);
            }
        } …
Run Code Online (Sandbox Code Playgroud)

c# synchronization semaphore async-await

5
推荐指数
1
解决办法
5814
查看次数

Blazor InvokeAsync 与 await InvokeAsync

编辑:为了澄清起见,这是在 Blazor 服务器应用程序中

我对 InvokeAsync 的正确用法和更新 UI 感到困惑。该文档有多种用法,但没有真正解释等待或不等待的原因。我也看到了一些相互矛盾的线索,但没有多少支持他们的推理。

使所有方法异步以等待 InvokeAsync(StateHasChanged) 似乎是错误的,我在某处读到引入 InvokeAsync 的原因是为了防止在任何地方都需要异步代码。但是在什么情况下我可能想要等待它?

等待:

https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-5.0&viewFallbackFrom=aspnetcore-3.0#invoke-component-methods-externally-to-update-state

非等待丢弃:

https://docs.microsoft.com/en-us/aspnet/core/blazor/components/rendering?view=aspnetcore-5.0

以下是我见过的一些不同用法的示例,如果有人可以解释或分享有关它们之间某些差异的信息的链接,那就太好了(谢谢!)

public void IncrementCounter()
{
    _counter++;
    InvokeAsync(StateHasChanged);
}
Run Code Online (Sandbox Code Playgroud)
public void IncrementCounter()
{
    InvokeAsync(() => 
    {
        _counter++;
        StateHasChanged);
    }
}
Run Code Online (Sandbox Code Playgroud)
public async Task IncrementCounter()
{
    _counter++;
    await InvokeAsync(StateHasChanged);
}
Run Code Online (Sandbox Code Playgroud)
public async Task IncrementCounter()
{
    await InvokeAsync(() =>
    {
        _counter++;
        StateHasChanged();
    });
}
Run Code Online (Sandbox Code Playgroud)

asynchronous invoke async-await blazor blazor-server-side

3
推荐指数
1
解决办法
825
查看次数

将 ManualResetEvent 与异步代码一起使用是否错误?

我正在寻找同步任务的最佳实践(甚至不确定这在语义上是否正确,我可能应该说用异步代码同步线程)。

采取以下代码:

Task.Run(async () => await lib.WaitAsync());
Task.Run(async () => await lib.WaitAsync());
Task.Run(async () => await lib.WaitAsync());

// Synchronize all waiters
lib.Release();

// All Tasks shall be completed
Run Code Online (Sandbox Code Playgroud)

在使用线程时,我曾经使用ManualResetEvent. 所以我的第一个(简化的)方法是:

Task WaitAsync()
{
   await Task.Run(() => manualResetEvent.WaitOne());
} 

void Release()
{
   manualResetEvent.Set();
} 
Run Code Online (Sandbox Code Playgroud)

现在我看到人们已经实现了自己的 async ManualResetEvent

原始方法有什么问题以及为什么有人更喜欢异步实现?是因为取消了吗?异常展开/处理?

更一般地说,在异步代码中使用常规线程同步对象(互斥量、信号量等)是否有任何缺点?

谢谢

c# multithreading asynchronous

2
推荐指数
1
解决办法
3980
查看次数

是否需要“ return wait Task.Run(() =&gt; PartialView()) ”?

我对c# 中的async 和await 了解一些。但我看到了如图所示的返回视图的方法。所以我想知道这个方法是如何实现的?

我已经做到了这一点,

public async Task<PartialViewResult> SamplePartialPage()
{
    ViewBag.countryList = await db.CountryList.ToListAsync();
    return PartialView();
}
Run Code Online (Sandbox Code Playgroud)

但不是这个。

public async Task<PartialViewResult> SamplePartialPage()
{
    ViewBag.countryList = await db.CountryList.ToListAsync();
    return await Task.Run(() => PartialView());
}
Run Code Online (Sandbox Code Playgroud)

c# task async-await

2
推荐指数
1
解决办法
404
查看次数

等待 Task.Delay() 花费太多时间

在 C# 中,我有一个例子:

public async static Task TaskTest(int i)
{
    await Task.Delay(1);
    Console.WriteLine($"{i}. {DateTime.Now.ToString("HH:mm:ss fff")} " +
        $"ThreadId:{Thread.CurrentThread.ManagedThreadId} Start");

    int count = 1;
    while (true)
    {
        DoSomeThing(count);

        var stopWatch = new Stopwatch();
        stopWatch.Start();

        await Task.Delay(100);

        stopWatch.Stop();
        if (stopWatch.Elapsed.TotalMilliseconds > 200)
            Console.ForegroundColor = ConsoleColor.Red;

        Console.WriteLine($"Id:{count} Time:{DateTime.Now.ToString("HH:mm:ss fff")} " +
         $"ThreadID:{Thread.CurrentThread.ManagedThreadId} Time Delay:{stopWatch.Elapsed.TotalMilliseconds }");

        Console.ForegroundColor = ConsoleColor.White;
        count++;
    }
}

public async static Task DoSomeThing(int index)
{
    await Task.Delay(1);
    Task.Delay(1000).Wait();
}

private static void Main(string[] args)
{
    int i = 1;
    while …
Run Code Online (Sandbox Code Playgroud)

c# multithreading task delay async-await

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

在只返回 Task 的异步方法上使用 await

在我的 ASP.NET Core 应用程序中,我以以下形式创建了几个(十几个)方法

public async Task DoStuff() 
{ 
   // ...
}
Run Code Online (Sandbox Code Playgroud)

所以,没有返回类型。

后来,我意识到我不小心忘记在调用方方法中到处包含此类方法(显然没有 async 关键字,因为异步“僵尸病毒”还没有传播那么远)。

在执行过程中,没有任何不良后果。

问题是,当这种事情发生时,Visual Studio 也不会生成任何警告消息,我问自己,在这种情况下,实际上是否存在忽略等待的危险?我知道 await 应该自然地应用于每个异步方法,但是当调用者实际上没有可使用的返回值时,我真的不明白这背后的原因。也许有捕获异常的东西?

我还没有找到任何明确的答案,因为一般声明是“只包含等待”。不管你信不信,这个异步/等待的东西,我相对较新,不时地反复咬我。

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

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