小编nos*_*tio的帖子

暂停/恢复异步任务的模式?

我有一个主要是IO绑定的连续任务(后台拼写检查器与拼写检查服务器通信).有时,此任务需要暂停并稍后恢复,具体取决于用户活动.

虽然暂停/恢复基本上是什么async/await,但我发现很少有关于如何为异步方法实现实际暂停/播放逻辑的信息.有推荐的模式吗?

我也考虑过使用Stephen Toub AsyncManualResetEvent,但认为这可能是一种矫枉过正.

.net c# asynchronous async-await

23
推荐指数
4
解决办法
2万
查看次数

Cancelling a pending task synchronously on the UI thread

Sometimes, once I have requested the cancellation of a pending task with CancellationTokenSource.Cancel, I need to make sure the task has properly reached the cancelled state, before I can continue. Most often I face this situation when the app is terminating and I want to cancel all pending task gracefully. However, it can also be a requirement of the UI workflow specification, when the new background process can only start if the current pending one has been fully …

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

22
推荐指数
3
解决办法
5104
查看次数

不同形式的WCF服务合同接口

看来我可以在同一个WCF合同接口API的以下三个不同版本之间自由切换,而不会破坏客户端:

[ServiceContract]
interface IService
{
    // Either synchronous
    // [OperationContract]
    // int SomeMethod(int arg);

    // Or TAP
    [OperationContract]
    Task<int> SomeMethodAsync(int arg);

    // Or APM
    // [OperationContract(AsyncPattern = true)]
    // IAsyncResult BeginSomeMethod(int arg, AsyncCallback callback, object state);
    // int EndSomeMethod(IAsyncResult ar);
}
Run Code Online (Sandbox Code Playgroud)

现有的测试客户端应用程序无需重新编译或触摸即可继续工作.如果我重新编译服务并将其引用重新导入客户端应用程序,则WSDL定义保持不变,1:1.

我的问题:

  • 这是我可以依赖的合法行为吗?是否记录在任何地方?

我们的想法是将一组同步SomeMethod方法转换为TAP SomeMethodAsync风格的方法,以便async/await在其实现中使用,从而提高WCF服务的可扩展性,而不会破坏现有客户端.

此外,已知在.NET 3.5和.NET 4.0下WCF服务扩展的问题.它们记录在MSKB文章"WCF服务可能在负载下缓慢扩展"和CodeProject文章"调整WCF以构建高度可伸缩的异步REST API"中.基本上,将服务契约API实现为自然异步是不够的,WCF运行时仍然阻塞了请求线程.

  • 有没有人知道这个问题是否已经为.NET 4.5.x修复,开箱即用?或者还需要额外的调整?

.net c# wcf asynchronous async-await

22
推荐指数
1
解决办法
4019
查看次数

"等待Task.Yield()"及其替代品

如果我需要推迟代码执行,直到UI线程消息循环的未来迭代之后,我可以这样做:

await Task.Factory.StartNew(
    () => {
        MessageBox.Show("Hello!");
    },
    CancellationToken.None,
    TaskCreationOptions.None,
    TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

这将类似于await Task.Yield(); MessageBox.Show("Hello!");,除了我有一个选项可以取消任务,如果我想.

在使用默认同步上下文的情况下,我可以类似地使用await Task.Run继续池线程.

事实上,我喜欢Task.Factory.StartNewTask.Run更多Task.Yield,因为他们都明确定义了延续代码的范围.

那么,在什么情况下await Task.Yield()实际上有用呢?

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

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

我以为还在和调用者在同一个线程上等待,但似乎没有

我认为关于async/await的一点是,当任务完成时,继续在调用await时在相同的上下文上运行,在我的情况下,这将是UI线程.

例如:

Debug.WriteLine("2: Thread ID: " + Thread.CurrentThread.ManagedThreadId);
await fs.ReadAsync(data, 0, (int)fs.Length);
Debug.WriteLine("3: Thread ID: " + Thread.CurrentThread.ManagedThreadId);
Run Code Online (Sandbox Code Playgroud)

我不指望这个:

2: Thread ID: 10
3: Thread ID: 11
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?为什么延续的线程ID与UI线程不同?

根据这篇文章 [^]我需要显式调用ConfigureAwait来改变连续上下文的行为!

c# multithreading asynchronous async-await

21
推荐指数
2
解决办法
4818
查看次数

默认SynchronizationContext与默认TaskScheduler

这会有点长,所以请耐心等待.

我在想默认任务scheduler(ThreadPoolTaskScheduler)的行为与默认的" ThreadPool" SynchronizationContext(后者可以通过await或显式地通过隐式引用)非常相似TaskScheduler.FromCurrentSynchronizationContext().它们都安排在随机ThreadPool线程上执行的任务.实际上,SynchronizationContext.Post只是打电话ThreadPool.QueueUserWorkItem.

但是,TaskCompletionSource.SetResult当从默认排队的任务中使用时,工作方式有一个微妙但重要的区别SynchronizationContext.这是一个简单的控制台应用程序说明它:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleTcs
{
    class Program
    {
        static async Task TcsTest(TaskScheduler taskScheduler)
        {
            var tcs = new TaskCompletionSource<bool>();

            var task = Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("before tcs.SetResult, thread: " + Thread.CurrentThread.ManagedThreadId);
                    tcs.SetResult(true);
                    Console.WriteLine("after tcs.SetResult, thread: " + Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(2000);
                },
                CancellationToken.None,
                TaskCreationOptions.None,
                taskScheduler);

            Console.WriteLine("before await tcs.Task, thread: " + Thread.CurrentThread.ManagedThreadId);
            await tcs.Task.ConfigureAwait(true); …
Run Code Online (Sandbox Code Playgroud)

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

20
推荐指数
1
解决办法
9105
查看次数

Electron v14 TypeScript 类型定义中缺少enableRemoteModule

我已经升级到 Electron 14,重构了我的项目以适应“已删除:远程模块”重大更改,但由于以下 TypeScript 错误,我无法编译它:

Type '{ plugins: true; nodeIntegration: true; contextIsolation: false; enableRemoteModule: true; backgroundThrottling: false; webSecurity: false; }' is not assignable to type 'WebPreferences'.

Object literal may only specify known properties, and 'enableRemoteModule' does not exist in type 'WebPreferences'.ts(2322)

electron.d.ts(12612, 5): The expected type comes from property 'webPreferences' which is declared here on type 'BrowserWindowConstructorOptions'
Run Code Online (Sandbox Code Playgroud)

受影响的代码:

const window = new electron.BrowserWindow({
    // ...
    webPreferences: { 
      plugins: true, 
      nodeIntegration: true, 
      contextIsolation: false,
      enableRemoteModule: true, 
      backgroundThrottling: false,
      webSecurity: …
Run Code Online (Sandbox Code Playgroud)

typescript electron

20
推荐指数
1
解决办法
1万
查看次数

重温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
查看次数

TAP全局异常处理程序

此代码抛出异常.是否可以定义将捕获它的应用程序全局处理程序?

string x = await DoSomethingAsync();
Run Code Online (Sandbox Code Playgroud)

使用.net 4.5/WPF

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

18
推荐指数
1
解决办法
3444
查看次数

CancellationToken.ThrowIfCancellationRequested后出现故障与已取消的任务状态

通常我不会回答问题,但这次我想引起一些我认为可能是一个模糊而又常见的问题的注意.它是由这个问题引发的,从那以后我查看了我自己的旧代码,发现其中一些也受此影响.

下面的代码开始,等待着两个任务,task1并且task2,这几乎是相同的.task1只是task2因为它运行一个永无止境的循环.对于执行CPU限制工作的一些现实场景,这两种情况都非常典型.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    public class Program
    {
        static async Task TestAsync()
        {
            var ct = new CancellationTokenSource(millisecondsDelay: 1000);
            var token = ct.Token;

            // start task1
            var task1 = Task.Run(() =>
            {
                for (var i = 0; ; i++)
                {
                    Thread.Sleep(i); // simulate work item #i
                    token.ThrowIfCancellationRequested();
                }
            });

            // start task2
            var task2 = Task.Run(() =>
            {
                for (var i = 0; …
Run Code Online (Sandbox Code Playgroud)

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

17
推荐指数
1
解决办法
4632
查看次数