Li muitos artigos introdutórios sobre como atualizar a interface principal no tópico em segundo plano, e a maioria deles usa Control.Invoke e Control.BeginInvoke. Essas são boas soluções, mas há dois problemas:
1. Você deve consultar System.Windows.Forms e, em seguida, usar System.Windows.Forms
2. A estrutura do código é relativamente bagunçada. (Na verdade, isso também é causado pelo #1)
A Microsoft oferece outra solução mais elegante, que é o System.Threading. SynchronizationContext。 Como você pode ver, não está no namesapce System.Windows.Forms, então podemos usá-lo legitimamente no BusinessLaryer, Control e até módulos.
E é muito conveniente de usar, você só precisa focar nos seguintes dois métodos:
1. Enviar: Envia uma solicitação de atualização de interface para a thread principal, bloqueando a thread atual até que ela retorne.
2. Post: Envia uma solicitação de atualização de interface para a thread principal sem bloquear a thread atual.
Na verdade, todos são o mesmo método, exceto que enviar é síncrono e post é assíncrono
Antes de Form1 form = new Form1(), o objeto SynchronizationContext estava vazio, e quando o formulário Form1 era instanciado, o objeto SynchronizationContext era adicionado a esse thread. Então, a resposta é que, quando o objeto Control é criado, o objeto SynchronizationContext também é criado e anexado à thread. Todos ao usar a forma InitializeComponent(); Depois disso, pode obter um objeto que não é NULL
Por fim, a diferença entre os métodos Sendt() e Post() do SynchronizationContext:
Send() é implementado simplesmente chamando o delegado na thread atual (chamada síncrona). Ou seja, a thread UI é chamada diretamente na subthread para executar, e a subthread continuará executada após a execução da thread UI.
Post() é implementado chamando um delegado no pool de threads (chamada assíncrona). Isso porque o subthread encontra um thread do pool de threads para ajustar o thread da interface, e o subthread executa diretamente seu próprio código sem esperar o fim do thread da UI. Código de teste:
Resultado:
Tópico principal da interface: 1 Tópico: 5 SynchContext:1
Resumo:O objeto SynchronizationContext na thread da interface, seja chamado na thread principal ou dentro da thread, será executado na thread principal, então quando há muito código demorado, isso fará a interface da interface travar ou fingir a morte!
Na verdadeA thread UI não usa a classe SynchronizationContext, mas WindowsFormsSynchronizationContextAqui é Dongdong.
Código-fonte System.Threading.SynchronizationContext:
Código-fonte WindowsFormsSynchronizationContext:
|