如何異步使用richtextbox?例如,我有一個類和一個記錄某種計算的事件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ExampleProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//I subscribe to an event that often sends messages
//and I want to display
var c = new Core();
c.Notify = DisplayMessage;
c.ExampleMethod();
}
private void DisplayMessage(object sender, LogEventArgs e)
{ //When a event arrives, transfer to richTextBox1
richTextBox1.AppendText("\r\n" e.Date.ToString("dd/MM/yyyy HH:mm:ss "), Color.SlateGray);
richTextBox1.AppendText(e.Message, Color.Blue);
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
}
class Core
{
public delegate void LogHandler(object sender, LogEventArgs e);
public event LogHandler Notify;
//
public void ExampleMethod()
{
//generate messages with a pause in a random value
var rand = new Random();
for (int i = 1; i < 10000; i )
{ var pause = rand.Next(50, 2000);
Thread.Sleep(pause);
Notify?.Invoke(this, new LogEventArgs($"logged {i} pause in miliseconds {pause}", DateTime.Now, MessageType.Notice));
}
}
} //The class in which log messages are placed
class LogEventArgs
{
public string Message { get; }
public DateTime Date { get; }
public MessageType MessageType { get; }
public LogEventArgs(string mes, DateTime date, MessageType messageType)
{
Message = mes;
Date = date;
MessageType = messageType;
}
}
enum MessageType
{
Notice,
Warning,
Error,
}
//Extension method to set line colors in RichTextBox
public static class RichTextBoxExtensions
{
public static void AppendText(this RichTextBox box, string text, Color color)
{
box.SelectionStart = box.TextLength;
box.SelectionLength = 0;
box.SelectionColor = color;
box.AppendText(text);
box.SelectionColor = box.ForeColor;
}
}
}
嘗試了后臺作業人員、任務、同步等選項,但沒有結果。我很驚訝 WinForms 已經存在多年并且微軟沒有向它們添加異步操作,例如AppendTextAsync(). 如何強制將文本異步添加到富文本框?
uj5u.com熱心網友回復:
在表單上放置另一個文本框
將此代碼粘貼到 Form1.cs 中所有內容的頂部:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ExampleProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
var c = new Core();
c.Notify = DisplayMessage;
await c.ExampleMethod();
}
private void DisplayMessage(object sender, LogEventArgs e)
{
richTextBox1.AppendText("\r\n" e.Date.ToString("dd/MM/yyyy HH:mm:ss "), Color.SlateGray);
richTextBox1.AppendText(e.Message, Color.Blue);
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
}
class Core
{
public delegate void LogHandler(object sender, LogEventArgs e);
public event LogHandler Notify;
public async Task ExampleMethod()
{
var rand = new Random();
for (int i = 1; i < 10000; i )
{ var pause = rand.Next(50, 200);
await Task.Delay(pause);
Notify?.Invoke(this, new LogEventArgs($"logged {i} pause in miliseconds {pause}", DateTime.Now, MessageType.Notice));
}
}
}
class LogEventArgs
{
public string Message { get; }
public DateTime Date { get; }
public MessageType MessageType { get; }
public LogEventArgs(string mes, DateTime date, MessageType messageType)
{
Message = mes;
Date = date;
MessageType = messageType;
}
}
enum MessageType
{
Notice,
Warning,
Error,
}
public static class RichTextBoxExtensions
{
public static void AppendText(this RichTextBox box, string text, Color color)
{
box.SelectionStart = box.TextLength;
box.SelectionLength = 0;
box.SelectionColor = color;
box.AppendText(text);
box.SelectionColor = box.ForeColor;
}
}
}
運行它,單擊按鈕,然后繼續在另一個文本框中輸入 - 它保持回應等。我不知道你需要等多久才能看到隨著 RTB 中的文本變得巨大而出現的重大減速......但是你真的應該定期查看你的日志,這樣你就不會在 RTB 中建立兆位元組的文本
winforms 中的異步并不是要使用某種異步方式來更新控制元件;控制元件只能由創建它們的執行緒訪問,因此我們通常要求該執行緒執行與控制元件的任何互動(但我認為這是一個視角問題:如果后臺執行緒要求 UI 執行緒更新控制元件,那么它是與后臺執行緒正在執行的任何作業異步完成) - 確保您對它們的訪問速度很快,使用異步方式完成繁重的作業(API 呼叫?),然后呼叫以讓您的 UI 執行緒更新控制元件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/361423.html
下一篇:如何從另一種形式訪問方法
