1

我怎么能转换方法:

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();                        
}

到异步。

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

4

3 回答 3

3

使用asyncand的部分原因await是为了避免回调。通过使用新的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);
};

这只是违背了使用新支持的目的(在某种程度上),因为主要优点之一是您不再需要传递回调并将您的逻辑“由内而外”。

于 2012-09-05T16:24:17.673 回答
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以便您可以将其与其他异步操作组合。

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

于 2012-09-05T16:23:39.947 回答
1

你会这样做:

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

实际上,它变得更简单。

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

于 2012-09-05T16:24:16.553 回答