更新日期1:
更多详细信息:线程 1 和 2 必须持续处于活动状态。线程 1 正在更新其 GUI 并执行 HTTP POST。线程 2 将 HTTPListener 用于传入的 HTTP POST,并将该数据提供给线程 1。因此,GUI 需要显示当前的文本框值,并在线程 2 提供数据时更新。Servy 或其他方法是否允许两个线程同时工作?看来主线程正在等待线程 2 完成它的工作。然后它接受 prepWork 并使用它。我在 Servy 的示例中进行了编码,但找不到带有 Task 类的 Run() 定义。它的图书馆没有这种方法。我在 VS 2010 上使用 Net 4.0。有没有等效的方法可以使用?Start() 也没有编译,我知道你只能运行一次任务。
原始问题:
我已经测试了可以成功启动我的事件并在事件处理程序中更新我的 GUI 文本框的代码,如果事件在我理解的 UI 线程 1 中启动。当我尝试调用线程 1 方法 Fire() 从我的独立线程 2 方法 PrepareDisplay(), Fire() 被调用并依次触发事件。我输入了一些线程安全的调用代码(模仿 MSDN 教程中的 WinForms 线程安全),但事件处理程序仍然没有更新文本框。单步执行代码时,似乎 InvokeRequired 为 false。我的最终目标是将数据从线程 2 传递到 UI 线程 1,并使用新数据更新文本框。我不明白为什么线程安全代码没有启用它。有人可以帮助我更好地理解这一点,以及我忽略了什么吗?下面是代码:
非常感谢,
namespace TstTxtBoxUpdate
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Aag_PrepDisplay aag_Prep1 = new Aag_PrepDisplay();
Thread AagPrepDisplayThread = new Thread(new ThreadStart(aag_Prep1.PrepareDisplay));
AagPrepDisplayThread.Start();
while(!AagPrepDisplayThread.IsAlive)
;
Thread.Sleep(1000);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new SetOperation());
}
}
}
namespace TstTxtBoxUpdate
{
// Thread 1: UI
public partial class SetOperation : Form
{
private string text;
public event Action<object> OnChDet;
delegate void SetTextCallback(string text);
private Thread demoThread = null;
public SetOperation()
{
InitializeComponent();
OnChDet += chDetDisplayHandler;
}
public void FireEvent(Aag_PrepDisplay aagPrep)
{
OnChDet(mName);
}
private void chDetDisplayHandler(object name)
{
this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));
this.demoThread.Start();
}
private void ThreadProcSafe()
{
this.SetText("402.5");
}
private void SetText(string text)
{
if(this.actFreqChan1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.actFreqChan1.Text = text;
}
}
}
}
namespace TstTxtBoxUpdate
{
// Thread 2: Data prepare
public class Aag_PrepDisplay
{
#region Fields
private Aag_PrepDisplay mAagPrep;
#endregion Fields
#region Properties
public Aag_PrepDisplay AagPrepDisp;
public Aag_PrepDisplay AagPrep
{
get { return mAagPrep; }
set { mAagPrep = value; }
}
#endregion Properties
#region Methods
public void PrepareDisplay()
{
mAagPrep = new Aag_PrepDisplay();
SetOperation setOp1 = new SetOperation();
setOp1.FireEvent(mAagPrep); // calls Thread 1 method that will fire the event
}
#endregion Methods
}
}