来自C#任务的通用回调

来自C#任务的通用回调,c#,callback,task-parallel-library,async-await,C#,Callback,Task Parallel Library,Async Await,从异步任务调用通用回调的推荐方法是什么?例如,进度、异常处理和完成(但可以是其他状态) 下面的代码显示了实现它的一种方法,但感觉应该有一种更干净的方法来处理这个问题。(FWIW我已经看到了很多使用ContinueWith作为完成回调的示例,但这并不能真正处理其他情况,如进度和异常处理) 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用系统线程; 使用System.Threading.Tasks; 命名空间测试代码 { 类T

异步任务调用通用回调的推荐方法是什么?例如,进度、异常处理和完成(但可以是其他状态)

下面的代码显示了实现它的一种方法,但感觉应该有一种更干净的方法来处理这个问题。(FWIW我已经看到了很多使用
ContinueWith
作为完成回调的示例,但这并不能真正处理其他情况,如进度和异常处理)

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
命名空间测试代码
{
类TestApp
{
公共静态void Main()
{
AsyncCallbackTest=新的AsyncCallbackTest();
test.RunTest();
}
}
接口ICallback
{
void onProgress(字符串状态);
无效未完成();
无效(例外e);
}
类AsyncCallbackTest:ICallback
{
公共无效运行测试()
{
//在后台运行任务
任务任务=新任务(新操作(ExampleTask),此);
task.Start();
//在这里做点别的
//...
//等待任务完成
task.Wait();
}
public void onProgress(字符串状态)
{
控制台输出写入线(状态);
}
未完成的公共无效()
{
控制台输出写入线(“已完成”);
}
公共void onFaulted(异常e)
{
Console.Out.WriteLine(“异常:+e.Message”);
}
私有void示例任务(对象ocb)
{
ICallback callback=ocb作为ICallback;
//做些工作
尝试
{
DoSomething(回调);
}
捕获(例外e)
{
//如何传递异常/错误?
回调。onFaulted(e);
}
}
//长时间运行的任务示例
私有void DoSomething(ICallback回调)
{
callback.onProgress(“启动”);
睡眠(5000);
callback.onProgress(“第1步完成”);
睡眠(5000);
callback.onProgress(“第2步完成”);
睡眠(5000);
callback.onCompleted();
}
}
}

您可以使用
IProgress
界面或其
进度
。您可以找到一篇描述其用法的博客文章,但它基本上类似于使用回调


使用@Kirill Shlenskiy建议的类似方法也可以是一种选择,但我认为向使用任务的现有方法中添加对该方法的支持可能不是最简单的解决方案。

使用
async
-
wait
完成和异常处理非常简单。进程处理正是
IProgress
界面的功能所在

因此,您的方法的签名类似于:

public Task DoSomething(IProgress<string> progress = null);

使用新的async/await,异常处理非常简单。等待任务时,任务中引发的任何未处理异常都会传播到等待者
public Task DoSomething(IProgress<string> progress = null);
try
{
    await DoSomething(new Progress<string>(status => Console.WriteLine(status)));
    Console.WriteLine("COMPLETED");
}
catch (Exception e)
{
    Console.WriteLine("EXCEPTION: " + e.Message);
}
DoSomething(new Progress<string>(status => Console.WriteLine(status)))
    .ContinueWith(t =>
        {
            if (t.Exception != null)
                Console.WriteLine("EXCEPTION: " + t.Exception.InnerException.Message);
            else
                Console.WriteLine("COMPLETED");
        });