s.k*_*aul 10 c# events multithreading backgroundworker winforms
我有一个从Queue类继承的自定义Queue类.它有一个事件ItemAdded.在此事件的事件处理程序中,我正在执行一个方法.但它运行的不是主线程,虽然我想在主线程中.我不知道怎么做.有什么建议吗?
//My custom class
using System;
using System.Collections; //Required to inherit non-generic Queue class.
namespace QueueWithEvent
{
public class SmartQueue:Queue
{
public delegate void ItemAddedEventHandler(object sender, EventArgs e);
public event ItemAddedEventHandler ItemAdded;
protected virtual void OnItemAdded(EventArgs e)
{
if (ItemAdded != null)
{
ItemAdded(this, e);
}
}
public override void Enqueue(object Item)
{
base.Enqueue(Item);
OnItemAdded(EventArgs.Empty);
}
}
}
//Winform application
using System;
using System.ComponentModel;
using System.Windows.Forms;
using QueueWithEvent;
namespace TestApp
{
public partial class Form1 : Form
{
SmartQueue qTest = new SmartQueue();
public Form1()
{
InitializeComponent();
qTest.ItemAdded += new SmartQueue.ItemAddedEventHandler(this.QChanged);
}
private void btnStartBgw_Click(object sender, EventArgs e)
{
DisplayThreadName();
bgwTest.RunWorkerAsync();
}
private void bgwTest_DoWork(object sender, DoWorkEventArgs e)
{
try
{
for (int i = 0; i < 11; i++)
{
string valueTExt = i.ToString();
qTest.Enqueue(valueTExt);
System.Threading.Thread.Sleep(5000);
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
private void DisplayThreadName()
{
string tName = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
txtThreadName.Text = tName;
}
private void QChanged(object sender, EventArgs e)
{
//#########I want this method to run on main thread #############
DisplayThreadName();
}
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.SKPaul.
Ser*_*kiy 22
您在后台线程上排队项目(DoWork事件处理程序在后台线程上运行),因此您的事件也在后台线程中引发.
使用InvokeRequired方法验证您是否在UI线程上.如果没有,那么使用Invoke在UI线程上运行代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
您的另一个选择 - 使用ProgressChanged事件来排队项目(不要忘记设置WorkerReportsProgress为true).此事件处理程序在UI线程上运行:
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35996 次 |
| 最近记录: |