2

我正在实现我自己的,我对我正在做的自定义 XML 序列化程序MediaTypeFormatter的方法有一些疑问:WriteToStreamAsync

public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)

我见过很多同步操作的例子,为了返回 a Task,它们将代码包含在 a 中Task.Factory.StartNew(),但是......可以吗?我的意思是,这不是让任务链接 IO 操作来提高可伸缩性吗?

我找到了两种可能的解决方案:

首先,我使用 aStreamWriter并返回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呢?

另一个,我使用内部内存流,并且WriteAsyncwriteStream

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

这将是最好的方法吗?

4

2 回答 2

3

当我知道一个操作将同步运行,但需要一个 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;
    }
于 2013-07-08T13:11:39.907 回答
0

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

我引用布拉德威尔逊的话。

于 2013-07-08T13:04:03.620 回答