将onCallback转换为Async

时间:2012-09-05 16:20:34

标签: c# multithreading task async-await

我该如何转换方法:

static void DoWork(Action<bool> onCompleteCallback)
{            
    Task doWork = new Task( ()=>Thread.Sleep(2000) );

    Action<Task> onComplete = (task) => {
        onCompleteCallback(true); // should execute on the main thread
    };

    doWork.ContinueWith(onComplete, TaskScheduler.FromCurrentSynchronizationContext());
    doWork.Start();                        
}

指向异步。

如果我将其转换为异步会有什么区别?

3 个答案:

答案 0 :(得分:3)

使用asyncawait的部分原因是为了避免回调。通过使用新的async支持,您的方法本身可以返回Task(或Task<T>),您可以在其上使用await,从而无需传入完全回调。

如果您想使用新的async / await设置,请将其写为:

static Task DoWork()
{
     return Task.Run( () => /* Your work */ Thread.Sleep(2000) );            
};

差异实际上在于你如何称呼它。您只需编写:

,而不是使用回调
await DoWork();
// Do your callback work here - it'll automatically be mapped into the right sync context and happen after the above completes

当然,您可以在静止中传递回调,并将其写为:

static async Task DoWork(Action<bool> onCompleteCallback)
{            
     await Task.Run( ()=>Thread.Sleep(2000) ); // Or use Task.Delay(2000) if you just want a pause...
     onCompleteCallback(true);
};

这恰好击败了使用新支持的目的(有些),因为其中一个主要优点是你不再需要传递回调并将你的逻辑“从里到外”。

答案 1 :(得分:1)

你通常会写:

static async Task DoWorkAsync(Action<bool> onCompleteCallback)
{            
    await Task.Delay(2000); // Simpler than starting a new task
    onComplete(true); // Will automatically be called on the original context
}

请注意,您的方法可以返回void,但从异步方法返回Task通常更简洁,以便您可以将其与其他异步操作组合在一起。

如评论中所述,您应该看看是否可以重新设计代码,因此您不需要传递回调。我们需要更多关于调用代码的上下文来进一步建议你。

答案 2 :(得分:1)

你会这样做:

static Task DoWork(Action<bool> onCompleteCallback)
{            
    await Task.Delay(2000);
    onCompleteCallback(true);
}

实际上它变得更简单了。

因为您的函数最初是从UI线程调用的,所以您可以调用回调,因为您的方法已经在UI线程上执行。