我想触发一个在后台线程上运行的任务.我不想等待任务完成.
在.net 3.5中,我会这样做:
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
Run Code Online (Sandbox Code Playgroud)
在.net 4中,TPL是建议的方式.我见过的常见模式是:
Task.Factory.StartNew(() => { DoSomething(); });
Run Code Online (Sandbox Code Playgroud)
但是,该StartNew()方法返回一个Task实现的对象IDisposable.推荐这种模式的人似乎忽视了这一点.有关该Task.Dispose()方法的MSDN文档说:
"在释放对任务的最后一个引用之前,始终调用Dispose."
你不能在任务完成之前调用dispose,所以让主线程等待并调用dispose会首先打破后台线程上的操作.似乎也没有任何已完成/已完成的事件可用于清理.
Task类上的MSDN页面没有对此进行评论,并且"Pro C#2010 ..."一书推荐了相同的模式,并且没有对任务处理做出评论.
我知道如果我离开它,终结者最终会抓住它,但当我做了大量的火灾并且忘记了这样的任务并且终结者线程被淹没时,它会回来咬我吗?
所以我的问题是:
Dispose()就Task在这种情况下类?如果是这样,为什么会有风险/后果?Task我错过的物体?我对CLR和GC的工作方式很着迷(我正在通过C#,Jon Skeet的书籍/帖子等阅读CLR来扩展我的知识).
无论如何,说:有什么区别:
MyClass myclass = new MyClass();
myclass = null;
Run Code Online (Sandbox Code Playgroud)
或者,通过使MyClass实现IDisposable和析构函数并调用Dispose()?
另外,如果我有一个带有using语句的代码块(例如下面的代码),如果我单步执行代码并退出using块,那么对象是在处理垃圾收集时发生的吗?如果我在使用块中调用Dispose()会发生什么?
using (MyDisposableObj mydispobj = new MyDisposableObj())
{
}
Run Code Online (Sandbox Code Playgroud)
流类(例如BinaryWriter)有一个Finalize方法吗?我为什么要用它?
我有一些二进制数据,我想保存为图像.当我尝试保存图像时,如果用于创建图像的内存流在保存之前关闭,则会引发异常.我这样做的原因是因为我正在动态创建图像,因此我需要使用内存流.
这是代码:
[TestMethod]
public void TestMethod1()
{
// Grab the binary data.
byte[] data = File.ReadAllBytes("Chick.jpg");
// Read in the data but do not close, before using the stream.
Stream originalBinaryDataStream = new MemoryStream(data);
Bitmap image = new Bitmap(originalBinaryDataStream);
image.Save(@"c:\test.jpg");
originalBinaryDataStream.Dispose();
// Now lets use a nice dispose, etc...
Bitmap2 image2;
using (Stream originalBinaryDataStream2 = new MemoryStream(data))
{
image2 = new Bitmap(originalBinaryDataStream2);
}
image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}
Run Code Online (Sandbox Code Playgroud)
有没有人对如何在关闭流的情况下保存图像有任何建议?我不能依赖开发人员记住在保存图像后关闭流.实际上,开发人员没有使用内存流生成映像的IDEA(因为它发生在其他地方的其他代码中).
我真的很困惑:(
我打电话给哪一个?
是否有必要同时打电话?
如果我已经打过其中一个,那么另一个会抛出异常吗?
如何创建一个实例System.IO.Stream stream.我的一个函数接收System.IO.Stream stream参数并写一些东西给它.那么如何创建相同的新实例并将其传递给函数呢?
在using语句中使用内存流时,是否需要调用close?例如这里需要ms.Close()吗?
using (MemoryStream ms = new MemoryStream(byteArray))
{
// stuff
ms.Close();
}
Run Code Online (Sandbox Code Playgroud) 我要将字节数组转换为System.Windows.Media.Imaging.BitmapImage并BitmapImage在图像控件中显示.
当我使用第一个代码时,注意到了!没有错误,也没有显示图像.但是当我使用第二个时,它工作正常!任何人都可以说发生了什么事吗?
第一个代码在这里:
public BitmapImage ToImage(byte[] array)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(array))
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = ms;
image.EndInit();
return image;
}
}
Run Code Online (Sandbox Code Playgroud)
第二个代码在这里:
public BitmapImage ToImage(byte[] array)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = new System.IO.MemoryStream(array);
image.EndInit();
return image;
}
Run Code Online (Sandbox Code Playgroud) 我有xml我得到的字节数组,最好的方法是从中获取xml字符串?我尝试使用xmltextreader和memorystream但没有成功..
我很开心System.Threading.Tasks.但是,我看到的许多代码示例都是这样的:
Dim lcTask = Task.Factory.StartNew(Sub() DoSomeWork())
Dim lcTaskLong = Task.Factory.StartNew(Sub() DoSomeWork(), TaskCreationOptions.LongRunning)
Task.WaitAll(lcTask, lcTaskLong)
Run Code Online (Sandbox Code Playgroud)
这就是样本的范围.
任务实现IDisposable,显然我应该处理它们,但如果我只是想要"消防和遗忘"怎么办?
如果我不处理,我会泄漏线程/句柄/记忆/业力吗?我使用"错误"的任务吗?(应该只使用代理并单独留下任务吗?)
我可以处理ContinueWith()吗?(这好像在玩俄罗斯轮盘赌.)
使用asp.net核心在HttpRequestMessage和HttpResponseMessage上调用Dispose(或不调用)的最佳实践是什么?
例子:
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
// Get the Google user
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
var response = await Backchannel.SendAsync(request, Context.RequestAborted);
response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
...
}
Run Code Online (Sandbox Code Playgroud)
和
https://github.com/aspnet/Security/blob/1.0.0/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs#L37-L40
这两个例子都没有调用Dispose
这可能是遗漏吗?或者它背后是否有正当理由,可能是因为该方法是异步的?当然,CG最终会最终确定它们,但这是在这种情况下这样做的最佳做法,为什么?请注意,上面的示例是ASP.NET Core Middleware组件的一部分.
c# ×9
.net ×4
bytearray ×2
dispose ×2
asp.net-core ×1
bitmapimage ×1
disposable ×1
exception ×1
gdi+ ×1
image ×1
memory ×1
memorystream ×1
stream ×1
using ×1
wpf ×1
xml ×1