我发现对于昂贵的IO绑定操作,我可以使用 TaskCompletionSource
如此处所示http://msdn.microsoft.com/en-us/library/hh873177.aspx#workloads
但是显示的示例只是等待一段时间并返回DateTime。
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;
}
上面的代码等待超时。我有一个数据库调用,我想以上述方式触发,但很少有人如何编写它:
using (var context = new srdb_sr2_context())
{
return context.GetData("100", "a2acfid");
}
我写了如下功能,但不确定这是正确的做法:
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;
任何帮助都将不胜感激。
答案 0 :(得分:1)
你的代码对我没有多大意义。如果您想在一段时间后执行代码,Timer
非常有用,但这不是您需要的。
如果要在后台线程上执行操作,可以使用Task.Run()
:
Task<IList<InstructorsOut>> GetDataBackground()
{
return Task.Run(() =>
{
using (var context = new srdb_sr2_context())
{
return context.GetData("100", "a2acfid");
}
});
}
使用后台线程这种方式在UI应用程序中非常有用,您不希望阻止UI线程。但是,如果你有像ASP.NET应用程序这样的东西,这实际上不会给你任何性能或可伸缩性改进。为此,GetData()
方法必须真正异步。