我远离应用程序。我长期以来更喜欢在应用程序中进行背景工作。Idle事件是多线程的简单替代方法。但是,对于长期运行的任务,在应用程序中运行操作是否可以接受。

class LongRunningTask : IDisposable {

    public LongRunningTask(IEnumerable<Tidbit> listOfDataToBeProcessed) {
       Application.Idle += OnIdle;

        foreach(Tidbit t in listofDataToBeProcessed) {
            tidbits.Enqueue(t);
        }
    }

    // Small pieces of data to process
    Queue<Tidbit> tidbits = new Queue<Tidbit>();

    void OnIdle(object sender, EventArgs e) {
        while(tidbits.Count > 0) {
            var tidbit = tasks.Dequeue();
            tidbit.Process();
            // Process any messages that have queued up
            // while the data was being processed
            Application.DoEvents();
        }
    }

    public void Dispose() {
        Application.Idle -= OnIdle;
    }
}

这里的逻辑是,在application.idle事件中,我们称之为doevents,没有排队的消息,因此我们不应该重新输入代码。每个小屋都会很快处理,以至于不应明显地固定消息队列(或UI)。

那么,这种方法是否有任何伤害或弊端?也就是说,在闲置事件中致电Doevents是安全的吗?我知道 C#5将具有解决这种情况的功能, ,但是对于那些不使用C#5的人(目前我们中的大多数人),并且出于一般好奇心,这是一个好计划吗?还是在长期运行过程中没有诉诸多线程的过程中处理消息的替代方案更简单?

请不要以为我认为这是一个魔术子弹。我知道它随之而来 与任何异步方法相同的陷阱. 。我知道,仍然必须能够将他的应用保持在一致的状态。和我 意识到有多线程解决方案。我避开那些。为什么?因为多线程更为复杂。我认为这是不切实际的。

有帮助吗?

解决方案

你在这里做的看起来很像 合作多任务处理. 。这是一个有趣的主意,但我想说您应该真正使用多线程进行这样的事情。 .NET有很多辅助系统 Task.Factory.StartNew() 以及真正变得容易的TPL库。

我建议不要这样做。

但是要明确:我没有明确的理由反对它。与许多有关编程的领域一样:如果起作用,则有效。但是,您将不应混合在一起的东西混合在一起,特别是背景任务和UI任务。我相信,当您将背景任务分开并开始使用时,通过多线程,线程池,背景任务和TPL弄脏双手时,您会很快看到它确实有效,从长远来看使生活更加轻松。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top