Yul*_*dra 15 .net c# multithreading dispose async-await
我正在努力使代码替换Thread为Task.睡眠/延迟只是代表长时间运行的活动.
static void Main(string[] args)
{
ThreadDoWork();
TaskDoWork();
}
public static void ThreadDoWork()
{
using (var dispose = new ThreadDispose())
{
dispose.RunAsync();
}
}
public static async void TaskDoWork()
{
using (var dispose = new TaskDispose())
{
await dispose.RunAsync();
}
}
public class ThreadDispose : IDisposable
{
public void RunAsync ()
{
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(3000);
});
}
void IDisposable.Dispose()
{
File.AppendAllText("D:\\test.txt", "thread disposing");
}
}
public class TaskDispose : IDisposable
{
public async Task RunAsync()
{
await Task.Delay(3000);
}
void IDisposable.Dispose()
{
File.AppendAllText("D:\\test.txt", "task disposing");
}
}
Run Code Online (Sandbox Code Playgroud)
3秒后的结果test.txt仅为
线程处理
我需要按顺序改变什么才能TaskDispose::Dispose执行ThreadDispose?
Yuv*_*kov 22
让我们隔离每段代码:
public static void ThreadDoWork()
{
using (var dispose = new ThreadDispose())
{
dispose.RunAsync();
}
}
public void RunAsync()
{
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(3000);
});
}
Run Code Online (Sandbox Code Playgroud)
你在第一段代码中所做的是在线程池线程上进行队列工作.因为您在using作用域内运行此代码并且它在不同的线程上异步运行,所以它会立即处理.这就是您在文本文件中看到dispose消息的原因.
public static async void TaskDoWork()
{
using (var dispose = new TaskDispose())
{
await dispose.RunAsync();
}
}
public class TaskDispose : IDisposable
{
public async Task RunAsync()
{
await Task.Delay(3000);
}
}
Run Code Online (Sandbox Code Playgroud)
当你await在你的方法中,你实际说的是:"执行这个代码.因为它本质上是异步的,我会将控制权返回给调用方法,一旦你完成异步操作,请给我回电话".
您的代码会点击await关键字并将控制权返回给您的Main方法.在内部Main,您的异步方法是要执行的最后一段代码,因此完成了您的应用程序,并且没有机会让您的Dispose方法执行.
如果你想将其配置,你就必须从改变返回类型void来Task并明确Wait:
public static async Task TaskDoWork()
{
using (var dispose = new TaskDispose())
{
await dispose.RunAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
现在:
static void Main(string[] args)
{
ThreadDoWork();
TaskDoWork().Wait();
}
Run Code Online (Sandbox Code Playgroud)
边注:
应遵循以下几条准则:
async void为了与事件处理程序兼容,在该范围之外很少会出现应该使用它的情况.相反,使用async Task.
使用TAP(任务异步模式)进行异步操作的方法应以Async后缀结束.TaskDoWork应该TaskDoWorkAsync
使用Wait上Task可能会导致死锁.在这种特殊情况下,它不会,因为控制台应用程序没有SynchronizationContext并使用线程池.推荐的方法是"一直异步"并使用await
async-await标签wiki里面有很棒的阅读材料,请务必查看.
| 归档时间: |
|
| 查看次数: |
12511 次 |
| 最近记录: |