相关疑难解决方法(0)

我什么时候会使用Task.Yield()?

我正在使用异步/等待和Task很多,但从来没有使用过Task.Yield(),说实话,即使有所有的解释,我不明白为什么我需要这种方法.

有人可以在Yield()需要的地方举个好例子吗?

c# async-await

196
推荐指数
4
解决办法
5万
查看次数

Task.Yield - 真实用法?

我一直在阅读有关Task.Yield,而且作为一名JavaScript开发,我可以告诉大家,就是它的工作是 完全相同一样setTimeout(function (){...},0);在让主单线程处理又名其他的东西方面:

"不要把所有的力量从时间上释放出来 - 所以其他人也会有一些......"

在js中,它特别适用于长循环.(不要让浏览器冻结......)

但我在这里看到了这个例子:

public static async Task < int > FindSeriesSum(int i1)
{
    int sum = 0;
    for (int i = 0; i < i1; i++)
    {
        sum += i;
        if (i % 1000 == 0) ( after a bulk , release power to main thread)
            await Task.Yield();
    }

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

作为JS程序员,我可以理解他们在这里做了什么.

但作为一名C#程序员,我问自己:为什么不为它开一个任务呢?

 public static async Task < int > FindSeriesSum(int i1)
    {
         //do something.... …
Run Code Online (Sandbox Code Playgroud)

c# multithreading async-await c#-5.0 .net-4.5

38
推荐指数
3
解决办法
2万
查看次数

重温Task.ConfigureAwait(continueOnCapturedContext:false)

阅读太久了.使用Task.ConfigureAwait(continueOnCapturedContext: false)可能会引入冗余线程切换.我正在寻找一致的解决方案.

长版.隐藏的主要设计目标ConfigureAwait(false)是在可能的情况下减少冗余的SynchronizationContext.Post延续回调await.这通常意味着更少的线程切换和更少的UI线程工作.但是,它并不总是如何运作.

例如,有一个实现SomeAsyncApiAPI的第三方库.请注意ConfigureAwait(false),由于某些原因,此库中的任何位置都不使用:

// some library, SomeClass class
public static async Task<int> SomeAsyncApi()
{
    TaskExt.Log("X1");

    // await Task.Delay(1000) without ConfigureAwait(false);
    // WithCompletionLog only shows the actual Task.Delay completion thread
    // and doesn't change the awaiter behavior

    await Task.Delay(1000).WithCompletionLog(step: "X1.5");

    TaskExt.Log("X2");

    return 42;
}

// logging helpers
public static partial class TaskExt
{
    public static void Log(string step)
    {
        Debug.WriteLine(new { step, thread = Environment.CurrentManagedThreadId }); …
Run Code Online (Sandbox Code Playgroud)

.net c# task-parallel-library async-await

19
推荐指数
2
解决办法
5006
查看次数

为什么从Async CTP/Release中删除"SwitchTo"?

我今天尝试使用SwitchTo方法切换到GUI线程,并发现我解除它的示例不起作用,仅仅是因为该方法不存在.

然后我在这里发现了这个模糊:

我们摆脱它的原因是因为它太危险了.另一种方法是在TaskEx.Run中捆绑你的代码......

我的问题很简单:为什么它很危险?使用它会带来哪些特定的危险?

请注意,我确实阅读了该帖子的其余部分,因此我确实理解这里存在技术限制.我的问题仍然是,如果我意识到这一点,为什么它很危险

我正在考虑重新实现帮助方法来给我指定的功能,但如果有一些根本性的破坏,除了有人认为它是危险的,我不会这样做.

具体来说,非常天真,这是我如何考虑实现所需的方法:

public static class ContextSwitcher
{
    public static ThreadPoolContextSwitcher SwitchToThreadPool()
    {
        return new ThreadPoolContextSwitcher();
    }

    public static SynchronizationContextSwitcher SwitchTo(this SynchronizationContext synchronizationContext)
    {
        return new SynchronizationContextSwitcher(synchronizationContext);
    }
}

public class SynchronizationContextSwitcher : INotifyCompletion
{
    private readonly SynchronizationContext _SynchronizationContext;

    public SynchronizationContextSwitcher(SynchronizationContext synchronizationContext)
    {
        _SynchronizationContext = synchronizationContext;
    }

    public SynchronizationContextSwitcher GetAwaiter()
    {
        return this;
    }

    public bool IsCompleted
    {
        get
        {
            return false;
        }
    }

    public void OnCompleted(Action action) …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous async-await async-ctp

13
推荐指数
2
解决办法
1114
查看次数

ConfigureAwait将继续推送到池线程

这是一个WinForms代码:

async void Form1_Load(object sender, EventArgs e)
{
    // on the UI thread
    Debug.WriteLine(new { where = "before", 
        Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread });

    var tcs = new TaskCompletionSource<bool>();

    this.BeginInvoke(new MethodInvoker(() => tcs.SetResult(true)));

    await tcs.Task.ContinueWith(t => { 
        // still on the UI thread
        Debug.WriteLine(new { where = "ContinueWith", 
            Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread });
    }, TaskContinuationOptions.ExecuteSynchronously).ConfigureAwait(false);

    // on a pool thread
    Debug.WriteLine(new { where = "after", 
        Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread });
}
Run Code Online (Sandbox Code Playgroud)

输出:

{ where = before, ManagedThreadId = 10, IsThreadPoolThread = False }
{ where = ContinueWith, …

.net c# multithreading task-parallel-library async-await

9
推荐指数
3
解决办法
3813
查看次数

异步和线程文化

我有一个MVC应用程序,我覆盖我的基本控制器的OnActionExecuting()方法来设置我的线程文化:

protected override void OnActionExecuting(ActionExecutingContext filterContext) {
    var langCode = GetLangCode();
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(langCode);
    Thread.CurrentThread.CurrentCulture = new CultureInfo(langCode);
}
Run Code Online (Sandbox Code Playgroud)

当我开始异步编程时,如果我们将我们修改过的文化返回到线程池,并且在异步任务完成时调度新线程,我很好奇文化是如何持久化的?我应该知道的任何陷阱?

c# asp.net-mvc async-await

8
推荐指数
1
解决办法
1013
查看次数

从SignalR集线器发送异步邮件

我需要通过SignalR集线器调用发送电子邮件.我不希望send同步执行,因为我不想绑定WebSocket连接,但是如果可能的话,我希望通知调用者是否有任何错误.我以为我可以在集线器中使用这样的东西(减去错误处理和我希望它做的所有其他事情):

public class MyHub : Hub {
    public async Task DoSomething() {
        var client = new SmtpClient();
        var message = new MailMessage(/* setup message here */);
        await client.SendMailAsync(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

但很快发现它不起作用; client.SendMailAsync调用抛出这个:

System.InvalidOperationException:此时无法启动异步操作.异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动.

进一步的调查和阅读告诉我,SmtpClient.SendMailAsync是围绕EAP方法的TAP包装器,而SignalR不允许这样做.

我的问题是,有没有简单的方法直接从集线器方法发送电子邮件?

或者我唯一的选择是将电子邮件发送到其他地方吗?(例如,让集线器队列成为服务总线消息,然后一个独立服务可以处理这些消息并发送电子邮件[虽然我也有更多的工作来实现结果通知回集中的客户端];或者让集线器向发送电子邮件的Web服务发出HTTP请求.

c# email smtpclient async-await signalr

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

在asp.net进程中运行多个并行任务的正确方法是什么?

我想我不懂东西.我原本以为Task.Yield()强制为一个任务启动一个新的线程/上下文,但是在重新阅读这个答案时,它似乎只是强制该方法是异步的.它仍然是在相同的背景下.

什么是正确的方法 - 在asp.net进程中 - 并行创建和运行多个任务而不会导致死锁?

换句话说,假设我有以下方法:

async Task createFileFromLongRunningComputation(int input) { 
    //many levels of async code
}
Run Code Online (Sandbox Code Playgroud)

当某个POST路由被命中时,我想同时启动上述方法3次,立即返回,但是当完成所有这三个时都要记录.

我想我需要把这样的东西放进我的行动中

public IHttpAction Post() {
   Task.WhenAll(
       createFileFromLongRunningComputation(1),
       createFileFromLongRunningComputation(2),
       createFileFromLongRunningComputation(3)
   ).ContinueWith((Task t) =>
      logger.Log("Computation completed")
   ).ConfigureAwait(false);
   return Ok();
Run Code Online (Sandbox Code Playgroud)

}

需要了解什么createFileFromLongRunningComputation?我原以为Task.Yield是正确的,但显然不是.

c# asp.net multithreading task-parallel-library async-await

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