非常感谢您在建议解决以下问题时的帮助。
问题描述: 在我的应用程序中,我在同一个线程上接收两个事件,两个事件处理程序都调用一个执行某项任务并在其中调用Application.DoEvents()的方法。
当我收到Event1时,它调用Event1_Handler,它调用DoWork。在DoWork中,我们调用Application.DoEvents()并等待循环达到.5秒,然后在线程泵中执行其他挂起事件,然后调用其他线程启动。 我们离开了'#34; Some Work"完成或我们等待.5秒然后离开任何方式。
所以来自Event1_Handler的DoWork尚未完成,同时收到Event2,它调用实时调用DoWork的Event2_Handler。这会产生不良行为。
这些事件总是按顺序排列,但可以在几毫秒之后发生。
using System;
using LoggerSpace;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace SyncMech
{
public delegate void MyDel();
public partial class Form1 : Form
{
event MyDel Event1;
event MyDel Event2;
public Form1()
{
InitializeComponent();
// Some logger initialization stuff
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
Trace.AutoFlush = true;
Trace.Indent();
}
private void Event2_Handler()
{
Logger.LogThisLine(">>> Event2_Handler");
DoWork();
Logger.LogThisLine("<<< Event2_Handler");
}
private void Event1_Handler()
{
Logger.LogThisLine(">>> Event1_Handler");
DoWork();
Logger.LogThisLine("<<< Event1_Handler");
}
public void DoWork()
{
Logger.LogThisLine(">>> DoWork");
for (int i = 0; i < 5; i++)
{
// We get out of loop after 500 ms or when Heavy work is completed
// completion of heavy work is notified by event hence Application.DoEvents is needed
Logger.LogThisLine("Heavy work");
Application.DoEvents();
Thread.Sleep(100);
}
Logger.LogThisLine("<<< DoWork");
}
public void RaiseEvents()
{
Event1.Invoke();
// have difference of 20 ms between both events
Thread.Sleep(20);
Event2.Invoke();
}
private void button2_Click(object sender, EventArgs e)
{
// Created a simple UI app with only one button
// Registered Event1 and Event2
this.Event1 += () => this.BeginInvoke((MethodInvoker)Event1_Handler);
this.Event2 += () => this.BeginInvoke((MethodInvoker)Event2_Handler);
// Raise both the events from background thread
new Thread(new ThreadStart(RaiseEvents)).Start();
}
}
}
输出:
8/5/2017 7:45:43 PM : >>> Event1_Handler
8/5/2017 7:45:43 PM : >>> DoWork
8/5/2017 7:45:43 PM : Heavy work
8/5/2017 7:45:43 PM : Heavy work
8/5/2017 7:45:43 PM : >>> Event2_Handler
8/5/2017 7:45:43 PM : >>> DoWork
8/5/2017 7:45:43 PM : Heavy work
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : <<< DoWork
8/5/2017 7:45:44 PM : <<< Event2_Handler
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : Heavy work
8/5/2017 7:45:44 PM : <<< DoWork
8/5/2017 7:45:44 PM : <<< Event1_Handler
这是一个非常古老的应用程序,DoWork是从这个应用程序的多个模块调用的,如果变更会产生很大的影响。我知道需要在Event_Handler2中完成的工作需要在Event_Handler1之后完成。当锁定在同一个线程上时,锁定不起作用。
问题:我如何确保Event_Handler2仅在Event_Handler1处理完成后才执行。还有其他任何建议。