【发布时间】:2020-10-02 06:22:16
【问题描述】:
我有这个(工作的)异步轮询回调循环的基本实现:
public void Start(ICallback callback)
{
if (Callback != null)
Stop();
Console.WriteLine("STARTING");
Callback = callback;
cancellation = new CancellationTokenSource();
this.task = Task.Run(() => TaskLoop(), cancellation.Token);
Console.WriteLine("STARTED");
}
public void Stop()
{
if (Callback == null)
{
Console.WriteLine("ALREADY stopped");
return;
}
Console.WriteLine("STOPPING");
cancellation.Cancel();
try
{
task.Wait();
}
catch (Exception e)
{
Console.WriteLine($"{e.Message}");
}
finally
{
cancellation.Dispose();
cancellation = null;
Callback = null;
task = null;
Console.WriteLine("STOPPED");
}
}
private void TaskLoop()
{
int i = 0;
while (!cancellation.IsCancellationRequested)
{
Thread.Sleep(1000);
Console.WriteLine("Starting iteration... {0}", i);
Task.Run(() =>
{
//just for testing
Callback.SendMessage($"Iteration {i} at {System.DateTime.Now}");
}).Wait();
Console.WriteLine("...Ending iteration {0}", i++);
}
Console.WriteLine("CANCELLED");
}
它实际上是通过 COM 从非托管 C++ 调用的,所以这是一个库项目(回调是一个 COM 编组的对象),因此想先测试设计。
我正在切换到使用async 范式,想知道它是否应该像在我的方法声明上撒一些async 灰尘并交换Wait() 调用await 一样简单?显然Thread.Sleep 将被更改为Task.Delay。
我相当肯定 COM 会为这个对象专门分配一个线程来进行封送处理,而非托管 C++ 不知道 .Net 异步模型,所以有什么需要注意的陷阱/陷阱吗?
这是我正在测试的更新版本,但是,就像资源管理一样,多线程是一个你的代码看起来可以完美运行但实际上非常糟糕的领域,所以我很感激你的想法:
public void Start(ICallback callback)
{
if (Callback != null)
Stop();
Console.WriteLine("STARTING");
Callback = callback;
cancellation = new CancellationTokenSource();
this.task = TaskLoopAsync();
Console.WriteLine("STARTED");
}
public async void Stop()
{
if (Callback == null)
{
Console.WriteLine("ALREADY stopped");
return;
}
Console.WriteLine("STOPPING");
cancellation.Cancel();
try
{
await task;
}
catch (Exception e)
{
Console.WriteLine($"{e.Message}");
}
finally
{
cancellation.Dispose();
cancellation = null;
Callback = null;
task = null;
Console.WriteLine("STOPPED");
}
}
private async void TaskLoopAsync()
{
int i = 0;
while (!cancellation.IsCancellationRequested)
{
await Task.Delay(1000);
Console.WriteLine("Starting iteration... {0}", i);
Callback.SendMessage($"Iteration {i} at {System.DateTime.Now}");
Console.WriteLine("...Ending iteration {0}", i++);
}
Console.WriteLine("CANCELLED");
}
【问题讨论】:
-
无需“休眠/延迟”并在
TaskLoop()中生成新任务。您可以直接拨打SendMessage()。 -
@Nick 是的,我想知道为什么我也添加了这个。我认为是在我试图诊断的一些问题期间,它从未被删除。
标签: c# .net async-await com task-parallel-library