Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在任务中使用语句_C#_Asp.net Web Api_Task Parallel Library_Using - Fatal编程技术网

C# 在任务中使用语句

C# 在任务中使用语句,c#,asp.net-web-api,task-parallel-library,using,C#,Asp.net Web Api,Task Parallel Library,Using,在ASP.NET Web API控制器中,我希望返回一个映像。对于流式传输图像,我需要一个MemoryStream。通常,我会使用语句将它包装在一个中,以确保它在之后得到正确处理。但是,由于这在任务中异步执行,因此不起作用: public class ImagesController : ApiController { private HttpContent GetPngBitmap(Stream stream) { var pngBitmapEncoder =

在ASP.NET Web API控制器中,我希望返回一个映像。对于流式传输图像,我需要一个
MemoryStream
。通常,我会使用语句将它包装在一个
中,以确保它在之后得到正确处理。但是,由于这在
任务中异步执行,因此不起作用:

public class ImagesController : ApiController
{
    private HttpContent GetPngBitmap(Stream stream)
    {
        var pngBitmapEncoder = new PngBitmapEncoder();
        pngBitmapEncoder.Save(stream);
        stream.Seek(0, SeekOrigin.Begin);
        return new StreamContent(stream);
    }

    // GET api/images
    public Task<HttpResponseMessage> Get(string id, string path)
    {            
        //do stuff           
        return Task.Factory.StartNew(() =>
        {
            var stream = new MemoryStream(); //as it's asynchronous we can't use a using statement here!
            {
                var response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = GetPngBitmap(stream)
                };
                response.Content.Headers.ContentType =
                    new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
                return response;
            }
            //how can I dispose stream???
        });
    }
}
公共类图像控制器:ApiController
{
私有HttpContent GetPngBitmap(流)
{
var pngBitmapEncoder=新的pngBitmapEncoder();
pngBitmapEncoder.Save(流);
stream.Seek(0,SeekOrigin.Begin);
返回新的StreamContent(流);
}
//获取api/图像
公共任务获取(字符串id、字符串路径)
{            
//做事
返回Task.Factory.StartNew(()=>
{
var stream=new MemoryStream();//因为它是异步的,所以这里不能使用using语句!
{
var响应=新的HttpResponseMessage(HttpStatusCode.OK)
{
Content=GetPngBitmap(流)
};
response.Content.Headers.ContentType=
新系统.Net.Http.Headers.MediaTypeHeaderValue(“image/png”);
返回响应;
}
//如何处理流???
});
}
}

也许这听起来很简单,但你不能在任务结束时处理它吗

var stream = new MemoryStream();
//use the stream...
stream.Dispose();
编辑:或“Close()”,它在MemoryStream上是相同的。

使用“using”,它将被自动处理

public class ImagesController : ApiController
{
    // GET api/images
    public Task<HttpResponseMessage> Get(string id, string path)
    {            
        //do stuff           
        return Task.Factory.StartNew(() =>
        {
           using( stream = new MemoryStream()) //as it's asynchronous we can't use a using statement here!
           {
            {
                var response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = GetPngBitmap(stream)
                };
                response.Content.Headers.ContentType =
                    new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
                return response;
            }
            //how can I dispose stream???
           }
        });
    }
}
公共类图像控制器:ApiController
{
//获取api/图像
公共任务获取(字符串id、字符串路径)
{            
//做事
返回Task.Factory.StartNew(()=>
{
using(stream=new MemoryStream())//由于它是异步的,所以这里不能使用using语句!
{
{
var响应=新的HttpResponseMessage(HttpStatusCode.OK)
{
Content=GetPngBitmap(流)
};
response.Content.Headers.ContentType=
新系统.Net.Http.Headers.MediaTypeHeaderValue(“image/png”);
返回响应;
}
//如何处理流???
}
});
}
}

可能返回一个
元组
,并附加一个继续任务来处理

public Task<Tuple<HttpResponseMessage,Stream>> Get(string id, string path)
{            
    //do stuff           
    return Task.Factory.StartNew(() =>
    {
        var stream = new MemoryStream();
        {
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = GetPngBitmap(stream)
            };
            response.Content.Headers.ContentType =
                new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
            return Tuple.Create(response, stream);
        }
    })
    .ContinueWith(t => t.Result.Item2.Close());
}
公共任务获取(字符串id、字符串路径) { //做事 返回Task.Factory.StartNew(()=> { var stream=newmemoryStream(); { var响应=新的HttpResponseMessage(HttpStatusCode.OK) { Content=GetPngBitmap(流) }; response.Content.Headers.ContentType= 新系统.Net.Http.Headers.MediaTypeHeaderValue(“image/png”); 返回Tuple.Create(响应、流); } }) .ContinueWith(t=>t.Result.Item2.Close()); }
你可以这样做。这将首先执行initialRun,在异步调用之后返回,然后执行continue with

        Task<System.IO.MemoryStream> initialRun = new Task<System.IO.MemoryStream>(() =>
        {
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            // use stream
            return stream;
        });
        initialRun.ContinueWith(new Action<Task<System.IO.MemoryStream>>((stream) =>
        {
            stream.Dispose();
        }), 
        TaskScheduler.FromCurrentSynchronizationContext());
        initialRun.Start();
Task initialRun=新任务(()=>
{
System.IO.MemoryStream stream=新的System.IO.MemoryStream();
//使用流
回流;
});
initialRun.ContinueWith(新操作((流)=>
{
stream.Dispose();
}), 
TaskScheduler.FromCurrentSynchronizationContext());
initialRun.Start();
  • MemoryStream
    是实现
    IDisposable
    的类之一,因为它们的基类实现IDisposable
    MemoryStream
    不包含任何资源(托管内存除外),因此实际上不需要处理它
  • HttpResponseMessage
    是一次性的。这意味着当它发送整个响应时,该对象被释放。这样做会处理包含的
    HttpContent
    ,在
    StreamContent
    的情况下,它会处理底层
    流。因此,即使您有一个应该被处理的
    ,在这种情况下您也不必担心它

  • 不,我不能。如果可能的话,我可以使用using语句。对不起,刚才看到返回语句是nsidewhat type is
    GetPngBitmap
    ,这就是本例中的关键。当“png位图”不再引用流时,处理流是有效的。在调用
    GetPnGBitmap()
    方法后调用dispose on stream?或者使用try finally block并在finally中调用Dispose,或者在返回响应之前调用Dispose。我看不出有什么问题?为什么不能使用呢?Web API宿主层负责在写入响应后在此处处理流,因此您无需担心自己关闭流……还有方法调用GetPngBitmap的作用?是否将内容从文件复制到内存流?如果是,您不需要再次创建内存流,而只需将文件流直接提供给内容作为
    StreamContent
    。@Caramiriel:我尝试过处理它,但没有成功。感谢代码…是的,流将被Web API的主机层关闭,因此,您不需要从您这边显式地执行任何操作…Web API的托管层将内容从内存流复制到网络流,然后关闭源流(内存流)…这与所有响应的行为大体相同..您是否在修改该行后阅读了注释?为什么会这样?因为当您使用“using”时,.net将调用“}”后面的.Dispose()对象。如果它之前存在(返回/异常),那么它无论如何都会发生。您应该阅读更多关于“使用”块的内容,并了解它的作用。谷歌ITOP表示,在这种情况下,不能使用“使用”。你确定这里可以用吗?(我不知道哪种方式,没有足够的工作经验。)