我正在实现自己的MediaTypeFormatter
,我对我正在做的自定义XML序列化程序的方法WriteToStreamAsync
有一些疑问:
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
我已经看到很多同步操作的示例,为了返回Task
,它们将代码括在Task.Factory.StartNew()
中,但是......可以吗?我的意思是,这是否超过了使用Task链接IO操作来提高可伸缩性的目的?
我找到了两种可能的解决方案:
首先,我使用StreamWriter
并返回FlushAsync
任务。
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
XDocument doc = new XDocument();
doc.Add(SerializeType(type, value));
var sw = new StreamWriter(writeStream,Encoding.UTF8,4096);
sw.AutoFlush = false;
doc.Save(sw);
return sw.FlushAsync();
}
我的问题是,之后StreamWriter
会发生什么?我想框架会处理writeStream
,但是StreamWriter
?
另一方面,我使用内部内存流,WriteAsync
使用writeStream
:
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
XDocument doc = new XDocument();
doc.Add(SerializeType(type, value));
Byte[] buffer = null;
using (var ms = new MemoryStream(4096))
{
doc.Save(ms);
buffer = ms.ToArray();
}
return writeStream.WriteAsync(buffer, 0, buffer.Length);
}
这是最好的方式吗?
答案 0 :(得分:2)
当我有一个我知道将要同步运行的操作但需要一个Task作为返回值时,我使用TaskCompletionSource实例来创建一个已完成的Task并返回它。
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
XDocument doc = new XDocument();
doc.Add(SerializeType(type, value));
doc.Save(writeStream);
var tcs = new TaskCompletionSource<object>();
tcs.SetResult(null);
return tcs.Task;
}
答案 1 :(得分:-1)
StartNew
用于计算绑定工作,而不用于I / O绑定。显然,给一个线程没有意义,因为该线程也必须等待。 MSDN说
仅在需要细粒度控制时才使用StartNew方法 一个长期运行的计算限制任务。
您可以使用using
这样的内容。
public override async Task WriteToStreamAsync(Type type, object value,
Stream stream,
HttpContent content,
TransportContext transportContext)
{
if (string.IsNullOrEmpty(JsonpCallbackFunction))
{
await base.WriteToStreamAsync(type, value, stream, content,
transportContext);
return;
}
using (var writer = new StreamWriter(stream))
{
writer.Write(JsonpCallbackFunction + "(");
writer.Flush();
await base.WriteToStreamAsync(type, value, stream, content,
transportContext);
writer.Write(")");
writer.Flush();
}
}
我引用Brad Wilson。