C# 调用在UI线程上操作的委托

C# 调用在UI线程上操作的委托,c#,wpf,multithreading,C#,Wpf,Multithreading,我在线程和UI代码方面遇到问题。我想要一个嵌套很深的子类来调用ui更改,写入文本框。这是一个新的线程。背景是我有一个服务器类,错误通知可以从不同线程上的不同客户端发出。我希望所有通知都在同一个文本框中结束。为了帮助调试,我对代码进行了大量简化,但我已经验证了它是否会再现错误。文本框中仅显示“hello2”,但我也希望显示“hello1” 尝试在日志文本框上设置TextWrapping=“Wrap”和AcceptsReturn=“True”。尝试在日志文本框上设置TextWrapping=“Wra

我在线程和UI代码方面遇到问题。我想要一个嵌套很深的子类来调用ui更改,写入文本框。这是一个新的线程。背景是我有一个服务器类,错误通知可以从不同线程上的不同客户端发出。我希望所有通知都在同一个文本框中结束。为了帮助调试,我对代码进行了大量简化,但我已经验证了它是否会再现错误。文本框中仅显示“hello2”,但我也希望显示“hello1”


尝试在日志文本框上设置
TextWrapping=“Wrap”
AcceptsReturn=“True”

尝试在日志文本框上设置
TextWrapping=“Wrap”
AcceptsReturn=“True”

您的
errormessenger
没有
通知程序。为什么?关键是调用
ehcontainer.NewWriteThread
时您正在创建一个新的
ehcontainer
——并且您从不将
通知程序从旧容器分配给新容器


如何解决这个问题完全取决于您的逻辑。我不知道你想做什么,也不知道你为什么选择这个解决方案。例如,为什么您使用C#6功能,却选择使用
线程
而不是
任务
。为什么?关键是调用
ehcontainer.NewWriteThread
时您正在创建一个新的
ehcontainer
——并且您从不将
通知程序从旧容器分配给新容器


如何解决这个问题完全取决于您的逻辑。我不知道你想做什么,也不知道你为什么选择这个解决方案。例如,为什么您使用C#6功能,却选择使用
线程
而不是
任务

谢谢,但我在文本框上运行AppendText。我会考虑使用消息传递,因为这一概念可以很好地解耦组件。看一看MvvM Light Toolkit Messenger。谢谢,但我正在文本框上运行AppendText。我会考虑使用消息传递,因为这个概念可以很好地解耦组件。查看MvvM Light Toolkit Messenger。
using System.Threading;
using System.Windows;

namespace WpfApplication1
{
public partial class MainWindow : Window
{
    ehcontainer ehc;

    public MainWindow()
    {
        InitializeComponent();

        ehc = new ehcontainer();
        ehc.eh.em.Notifier = WriteToTextBox;
    }

    // Attempting to only run from UI thread
    private void WriteToTextBox(string message)
    {
        if (!log_TextBox.CheckAccess())
        {
            Dispatcher.Invoke(() => apptext(message));
            return;
        }

        apptext(message);
    }

    private void apptext(string message)
    {
        log_TextBox.AppendText(message + "\n");
    }

    // Only hello2 is written to text box
    private void button_Click(object sender, RoutedEventArgs e)
    {
        ehc.NewWriteThread("hello1");
        ehc.Write("hello2");
    }
}

public class ehcontainer
{
    public errorhandler eh = new errorhandler();

    public void NewWriteThread(string message)
    {
        ehcontainer tempEHC = new ehcontainer();
        Thread newThread = new Thread(tempEHC.Write);
        newThread.Start(message);
    }

    public void Write(object obj)
    {
        string sMessage = (string)obj;

        eh.em.Notify(sMessage);
    }
}

public class errorhandler
{
    public errormessenger em;

    public errorhandler()
    {
        em = new errormessenger();
    }
}

public class errormessenger
{
    public delegate void NotifyMethod(string message);
    private NotifyMethod myNotifyMethod = null;

    public NotifyMethod Notifier
    {
        get { return myNotifyMethod; }
        set { myNotifyMethod = value; }
    }

    // Run a delegate that calls some notification function in UI thread
    public void Notify(string message)
    {
        myNotifyMethod?.Invoke(message);
    }
}
}