Execute a method in main thread from event handler

倖福魔咒の 提交于 2019-12-05 03:06:26

You are enqueueing items on background thread (DoWork event handler runs on background thread), thus your event raised also in background thread.

Use InvokeRequired method to verify if you are on UI thread. And if not, then use Invoke to run code on UI thread:

 private void QChanged(object sender, EventArgs e)
 {
     if (InvokeRequired)
     {
         Invoke((MethodInvoker)delegate { QChanged(sender, e); });
         return;
     }
     // this code will run on main (UI) thread 
     DisplayThreadName();
 }

Another option for you - use ProgressChanged event to enqueue items (don't forget to set WorkerReportsProgress to true). This event handler runs on UI thread:

private void bgwTest_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker)sender;

    for (int i = 0; i < 11; i++)
    { 
        // use user state for passing data
        // which is not reflecting progress percentage
        worker.ReportProgress(0, i);
        System.Threading.Thread.Sleep(5000);
    }
}

private void bgwTest_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
     string valueTExt = e.UserState.ToString();
     qTest.Enqueue(valueTExt);
}

You can use the same approach as the BackgroundWorker, that is incorporating AsyncOperation as a member in your class, which can dispatch operations to a thread it has been created in.

protected AsyncOperation AsyncOp;

Instantiate it in your constructor with "null" argument. That creates an async operation "bound" to the current thread.

public SmartQueue()
{
    AsyncOp = AsyncOperationManager.CreateOperation(null);
}

Then you can use the AsyncOp to Post your event.

public override void Enqueue(object Item)
{
    base.Enqueue(Item);
    AsyncOp.Post(OnItemAdded, EventArgs.Empty);
}

That will execute the OnItemAdded handlers (subscribers) on the same thread that created the SmartQueue instance.

Try with this code in main thread:

SmartQueue smartQueue = new SmartQueue();

public Form1()
{
    InitializeComponent();
    smartQueue.ItemAdded += new SmartQueue.ItemAddedEventHandler(smartQueue_ItemAdded);
}

void smartQueue_ItemAdded(object sender, EventArgs e)
{
    // add your code in here
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!