C# 如何编写在每次迭代时暂停的同步任务,以允许线程继续,直到线程再次空闲
我不确定我想要什么是可能的 我正在为一个主机应用程序编写一个插件,它为我提供了一个我希望处理的对象。限制是我必须只在主机主应用程序线程上处理这些对象。如果我用另一根线碰它们,宿主就会死亡 我已经编写了一个模拟场景,演示了这种情况,并通过评论指出了我想做什么。基本上我得到了一堆要处理的对象。我想做一个任务(我想),它可以在主机空闲时一次迭代处理一个对象,但每次迭代时都会将控制传递回线程,以便主机可以更新其空闲状态(通过事件)如果主机说忙,那么我希望将处理任务挂起,直到主机返回空闲状态 我想象它类似于下面的代码。但是我不知道如何解决这个问题,我甚至不确定使用C# 如何编写在每次迭代时暂停的同步任务,以允许线程继续,直到线程再次空闲,c#,task,C#,Task,我不确定我想要什么是可能的 我正在为一个主机应用程序编写一个插件,它为我提供了一个我希望处理的对象。限制是我必须只在主机主应用程序线程上处理这些对象。如果我用另一根线碰它们,宿主就会死亡 我已经编写了一个模拟场景,演示了这种情况,并通过评论指出了我想做什么。基本上我得到了一堆要处理的对象。我想做一个任务(我想),它可以在主机空闲时一次迭代处理一个对象,但每次迭代时都会将控制传递回线程,以便主机可以更新其空闲状态(通过事件)如果主机说忙,那么我希望将处理任务挂起,直到主机返回空闲状态 我想象它类似
Task/Async
主体是否可能
public class MockHost
{
public event EventHandler Idle;
public event EventHandler Busy;
public event EventHandler<ModifiedObjectsEventArgs> IHaveModifiedObjectsHereYouGo;
}
public class ModifiedObjectsEventArgs: EventArgs
{
public object[] ModifiedObjects;
}
public class TestClass
{
MockHost _host = new MockHost();
ObjectProcessor _processor = new ObjectProcessor();
public TestClass()
{
_host.Idle += _host_Idle;
_host.Busy += _host_Busy;
_host.IHaveModifiedObjectsHereYouGo += _host_IHaveModifiedObjectsHereYouGo;
}
private async void _host_IHaveModifiedObjectsHereYouGo(object sender, ModifiedObjectsEventArgs e)
{
await _processor.ProcessObjectsAsync(e.ModifiedObjects);
}
private void _host_Busy(object sender, EventArgs e)
{
_processor.SetHostBusyState(true);
}
private void _host_Idle(object sender, EventArgs e)
{
_processor.SetHostBusyState(false);
}
}
public class ObjectProcessor
{
bool _hostIsBusy = false;
public void SetHostBusyState(bool isBusy)
{
_hostIsBusy = isBusy;
if(!_hostIsBusy)
{
// Continue processing.
}
}
public async Task ProcessObjectsAsync(Object[] objects)
{
foreach(object obj in objects)
{
if (_hostIsBusy)
{
// suspend this task somehow
}
else
{
ProcessObject(obj);
}
// suspend the task somehow to let the host events update busy status if they need to.
}
}
private void ProcessObject(object obj)
{
// Long running process.
}
}
公共类MockHost
{
公共事件处理程序空闲;
公共事件处理程序忙;
公共事件处理程序IHaveModifiedObjectsHereYouGo;
}
公共类ModifiedObjectsEventArgs:EventArgs
{
公共对象[]修改对象;
}
公共类TestClass
{
MockHost _host=new MockHost();
ObjectProcessor_processor=新的ObjectProcessor();
公共测试类()
{
_host.Idle+=\u host\u Idle;
_host.Busy+=\u host\u Busy;
_host.IHaveModifiedObjectsHereYouGo+=\u host\u IHaveModifiedObjectsHereYouGo;
}
私有异步void _host_iHaveModifiedObjectShereyYouGo(对象发送方,ModifiedObjectsEventArgs e)
{
wait _processor.ProcessObjectsAsync(e.ModifiedObjects);
}
私有无效\u主机\u忙(对象发送方,事件参数e)
{
_processor.SetHostBusyState(true);
}
私有无效\u主机\u空闲(对象发送方,事件参数e)
{
_processor.SetHostBusyState(false);
}
}
公共类对象处理器
{
bool\u hostIsBusy=false;
public void SetHostBusyState(bool isBusy)
{
_hostIsBusy=isBusy;
如果(!\u主机忙)
{
//继续处理。
}
}
公共异步任务ProcessObjectsAsync(对象[]对象)
{
foreach(对象中的对象对象对象)
{
如果(主机忙)
{
//以某种方式暂停这项任务
}
其他的
{
ProcessObject(obj);
}
//以某种方式挂起任务,以便主机事件在需要时更新忙碌状态。
}
}
私有void ProcessObject(object obj)
{
//长时间运行的过程。
}
}
您可以随时使用以下方法将控制权交还给主机:
await Task.Yield();
这假定主机已设置同步上下文
它所做的是结束当前任务,并将延续发布回同步上下文。通过这种方式,主机可以取回线程,运行它需要的任何代码,然后将控制权交还给您的继续。而不是在UI线程中执行长时间运行的非UI工作,尝试停止一段时间,让UI事件得到处理,只是不要在UI线程中执行非UI工作,也不要在非UI线程中执行非UI工作。我别无选择,它是由我无法控制的主机强制执行的。我只能在主机应用程序线程上与它的对象进行交互。如果要临时将控制权交还给主机,可以使用
wait Task.Yield()
(假设主机设置了同步上下文)@KevinGosse谢谢我现在正在查看Task.Yield()。你知道如何使用它的好例子吗?@John只是把wait Task.Yield()放在上面代码>无论您在何处评论“以某种方式暂停任务”