Ant*_*nyM 4 c# multithreading dispatcher
我想要一个可以安排工作的专用线程。我可以使用dispatcher.invoke来做到这一点还是我必须做一些自定义的事情?
看起来调度程序应该可以工作,但我不知道如何实际让线程开始处理调度程序的工作。
我看到的唯一问题是如何判断线程的调度程序何时启动并运行,并准备好接受命令。Thread.Sleep(100)为此我添加了一个。没有它 aTaskCanceledException就会被抛出。
Thread.CurrentThread.Name = "Main";
var thread = new Thread(() =>
{
Console.WriteLine($"{Thread.CurrentThread.Name} Started");
Dispatcher.Run();
Console.WriteLine($"{Thread.CurrentThread.Name} Finished");
});
thread.IsBackground = true;
thread.Name = "Worker";
thread.Start();
Thread.Sleep(100);
Dispatcher dispatcher = Dispatcher.FromThread(thread);
dispatcher.Invoke(() =>
{
Console.WriteLine($"Processed by {Thread.CurrentThread.Name}");
});
dispatcher.InvokeShutdown();
thread.Join();
Run Code Online (Sandbox Code Playgroud)
输出:
工人开始
由工人处理
工人完成
更新:可以使用BlockingCollection. 下面的类有许多缺失的功能(取消、超时、参数、处置等),但提供了可以由多个工作线程共享的重要优势。
public class CustomDispatcher
{
private readonly BlockingCollection<(Action Action,
TaskCompletionSource<bool> TCS)> _blockingCollection =
new BlockingCollection<(Action, TaskCompletionSource<bool>)>();
public void Run()
{
foreach (var item in _blockingCollection.GetConsumingEnumerable())
{
try
{
item.Action.Invoke();
item.TCS.SetResult(true);
}
catch (Exception ex)
{
item.TCS.TrySetException(ex);
}
}
}
public Task InvokeAsync(Action action)
{
var tcs = new TaskCompletionSource<bool>();
_blockingCollection.Add((action, tcs));
return tcs.Task;
}
public void Invoke(Action action) => InvokeAsync(action).Wait();
public void InvokeShutdown() => _blockingCollection.CompleteAdding();
}
Run Code Online (Sandbox Code Playgroud)
更新:关于内置,可以使用 a 进行精确控制,Dispatcher而不是使用混乱的方式Thread.Sleep(100)给调度程序启动时间:TaskCompletionSource<Dispatcher>
Thread.CurrentThread.Name = "Main";
var dispatcherReady = new TaskCompletionSource<Dispatcher>();
var thread = new Thread(() =>
{
Console.WriteLine($"{Thread.CurrentThread.Name} Started");
dispatcherReady.SetResult(Dispatcher.CurrentDispatcher);
Dispatcher.Run();
Console.WriteLine($"{Thread.CurrentThread.Name} Finished");
});
thread.IsBackground = true;
thread.Name = "Worker";
thread.Start();
var dispatcher = dispatcherReady.Task.Result;
dispatcher.Invoke(() =>
{
Console.WriteLine($"Processed by {Thread.CurrentThread.Name}");
});
dispatcher.InvokeShutdown();
thread.Join();
Run Code Online (Sandbox Code Playgroud)
输出:
工人开始
由工人处理
工人完成
| 归档时间: |
|
| 查看次数: |
3325 次 |
| 最近记录: |