Parallel processing 如何使用任务并行库实现异步方法进行I/O操作

Parallel processing 如何使用任务并行库实现异步方法进行I/O操作,parallel-processing,task-parallel-library,async-await,c#-5.0,parallel-extensions,Parallel Processing,Task Parallel Library,Async Await,C# 5.0,Parallel Extensions,我发现对于昂贵的IO绑定操作,我可以使用TaskCompletionSource 如图所示 但显示的示例只是等待一段时间和返回日期时间 public static Task<DateTimeOffset> Delay(int millisecondsTimeout) { TaskCompletionSource<DateTimeOffset> tcs = null; Timer timer = null; timer = new Timer(delegate {

我发现对于昂贵的IO绑定操作,我可以使用TaskCompletionSource

如图所示

但显示的示例只是等待一段时间和返回日期时间

public static Task<DateTimeOffset> Delay(int millisecondsTimeout)
{
 TaskCompletionSource<DateTimeOffset> tcs = null;
 Timer timer = null;

 timer = new Timer(delegate
 {
    timer.Dispose();
    tcs.TrySetResult(DateTimeOffset.UtcNow);
 }, null, Timeout.Infinite, Timeout.Infinite);

 tcs = new TaskCompletionSource<DateTimeOffset>(timer);
 timer.Change(millisecondsTimeout, Timeout.Infinite);
 return tcs.Task;
}
我编写了如下函数,但不确定这是否是正确的方法:

TaskCompletionSource<IList<InstructorsOut>> tcs = null;
        Timer timer = null;

        timer = new Timer(delegate
        {
            timer.Dispose();

            //prepare for expensive data call
            using (var context = new srdb_sr2_context())
            {
                var output = context.GetData("100", "a2acfid");

                //set the result
                tcs.TrySetResult(output);
            }  

        }, null, Timeout.Infinite, Timeout.Infinite);

        tcs = new TaskCompletionSource<IList<InstructorsOut>>(timer);
        timer.Change(0, Timeout.Infinite);
        return tcs.Task;
TaskCompletionSource tcs=null;
计时器=空;
定时器=新定时器(委托
{
timer.Dispose();
//为昂贵的数据通话做好准备
使用(var context=new srdb\u sr2\u context())
{
var输出=context.GetData(“100”,“a2acfid”);
//设定结果
tcs.TrySetResult(输出);
}  
},null,Timeout.Infinite,Timeout.Infinite);
tcs=新任务完成源(计时器);
timer.Change(0,Timeout.Infinite);
返回tcs.Task;

任何帮助都将不胜感激。

您的代码对我来说没有多大意义<如果您想在一段时间后执行代码,则代码>计时器很有用,但这不是您需要的

如果要在后台线程上执行操作,可以使用
Task.Run()

Task GetDataBackground()
{
返回任务。运行(()=>
{
使用(var context=new srdb\u sr2\u context())
{
返回context.GetData(“100”,“a2acfid”);
}  
});
}

这种方式使用后台线程在UI应用程序中非常有用,因为您不想阻止UI线程。但是,如果您有类似ASP.NET的应用程序,这实际上不会给您带来任何性能或可伸缩性改进。为此,必须使
GetData()
方法真正异步。

这正是我的问题:如何使GetData()真正异步。我还添加了MSDN链接,其中显示了如何使用计时器来执行此操作。当然,您不能(假设您不能直接修改
GetData()
)。包含
GetData()
的库的作者必须这样做。GetData()是实体框架函数导入。因此,由于EF 5.0不支持异步操作,所以我无法在那里做任何事情。@SanjaySutar在这种情况下,您无能为力(除了切换到EF 6.0)。造成混淆的原因是TaskCompletionSource不是关于运行IO绑定的操作。它是关于在其他异步操作上提供一个基于任务的包装器,例如计时器延迟、事件、callbakcs。此外,数据库操作不是IO绑定的操作。在等待结果时,他们实际上只有很少的IO
TaskCompletionSource<IList<InstructorsOut>> tcs = null;
        Timer timer = null;

        timer = new Timer(delegate
        {
            timer.Dispose();

            //prepare for expensive data call
            using (var context = new srdb_sr2_context())
            {
                var output = context.GetData("100", "a2acfid");

                //set the result
                tcs.TrySetResult(output);
            }  

        }, null, Timeout.Infinite, Timeout.Infinite);

        tcs = new TaskCompletionSource<IList<InstructorsOut>>(timer);
        timer.Change(0, Timeout.Infinite);
        return tcs.Task;
Task<IList<InstructorsOut>> GetDataBackground()
{
    return Task.Run(() =>
    {
        using (var context = new srdb_sr2_context())
        {
            return context.GetData("100", "a2acfid");
        }  
    });
}