Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
609 views
in Technique[技术] by (71.8m points)

c# - How to access a WinForms control from another thread i.e. synchronize with the GUI thread?

I'm working on C# winforms app and i need to know how to manupilate a code into a thread by changing checkbox value.

 new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;

            TcpListener server = null;
            while (true)
            {
                if(){}else{}// here I need to check my checkbox
}}).Start();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use this:

new Thread(() =>
{
  Thread.CurrentThread.IsBackground = true;

  TcpListener server = null;

  while (true)
  {
    ...
    this.SynUI(()=>
    {
      if ( checkbox.Checked )
      {
      }
    });
    ...
  }
}).Start();

Or:

...
bool checked = false;
this.SynUI(()=> { checked = checkbox.Checked; });
...

Having:

static public class SyncUIHelper
{

  static public Thread MainThread { get; private set; }

  // Must be called from Program.Main
  static public void Initialize()
  {
    MainThread = Thread.CurrentThread;
  }

  static public void SyncUI(this Control control, Action action, bool wait = true)
  {
    if ( control == null ) throw new ArgumentNullException(nameof(control));
    if ( !Thread.CurrentThread.IsAlive ) throw new ThreadStateException();
    Exception exception = null;
    Semaphore semaphore = null;
    Action processAction = () =>
    {
      try
      {
        action();
      }
      catch ( Exception ex )
      {
        exception = ex;
      }
    };
    Action processActionWait = () =>
    {
      processAction();
      semaphore?.Release();
    };
    if ( control.InvokeRequired && Thread.CurrentThread != MainThread )
    {
      if ( wait ) semaphore = new Semaphore(0, 1);
      control.BeginInvoke(wait ? processActionWait : processAction);
      semaphore?.WaitOne();
    }
    else
      processAction();
    if ( exception != null )
      throw exception;
  }

}

Adding in the Program.Main before the Application.Run:

SyncUIHelper.Initialize();

You can find on stack overflow various ways to synchronize threads with the UI thread like:

How do I update the GUI from another thread?

Update UI from Class (multithreaded)?

Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on

There is BackgroundWorker too.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...