如何从 Nancyfx 启动的工作线程在主线程中 运行? C#

How to run in main thread from worker thread that start by Nancyfx? C#

我在我的 winform 应用程序中使用 nancyfx 时遇到问题(我制作了一个 winform 应用程序并在应用程序中使用了 nancyfx)所以我可以使用一些 API url 来改变没有额外服务器或服务的 winform(因为我在 winform 应用程序中附加了 nancy)

这是我的 Form1.cs

public partial class Form1 : Form 
{

    public Form1(bool test)
    {
        InitializeComponent();

        textBox1.Text += "Apps Method "+ Environment.NewLine;

    }

    public bool startTestAPI()
    {
        textBox1.Text += "Api Worked" + Environment.NewLine);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        HostingAPI s = new HostingAPI();
        s.Start();
        textBox1.Text += "Api Running" + Environment.NewLine);
    }
}


public class ModuleCDM : NancyModule
{

    public ModuleCDM()
    {
        try
        {
            Thread th2 = Thread.CurrentThread;
            Get["/Start"] = parameters =>
            {

                Form1 form = new Form1(false);
                Thread testthread = Form1.curthread;

                bool res = form.startTestAPI();

                if (res == true)
                {
                    var feeds = new string[] { "Success" };
                    return Response.AsJson(feeds);
                }
                else
                {
                    var feeds = new string[] { "Failed" };
                    return Response.AsJson(feeds);
                }
            };
    }
}
}

这是我的 HostingAPI.cs

public class HostingAPI
{
    private NancyHost hostNancy;

    private string hostUrl;

    public void Start()
    {
        hostUrl = ConfigModule.ModuleAddress;

        if (hostUrl == null) hostUrl = "http://localhost:5005";

        hostNancy = new NancyHost(new Uri(hostUrl));

        hostNancy.Start();

    }

    public void Stop()
    {
        hostNancy.Stop();
    }
}

它成功 运行 没有错误,但是当我调用 api (localhost:5005/Start) 时,winform 应用程序中的文本框没有添加我想要的文本 ("Api Worked") .我注意到这是因为 Nancyfx 在有 API 调用时创建另一个线程,我可以使用 invoke/begininvoke 因为 !invokerequired 总是带有值 false。那么当我调用 API.

时,如何访问主线程或更新 UI 的另一种解决方案

谢谢

这里有 2 个问题。

  1. 您从 Form1 实例启动主机 api 服务,然后在 Nancy 模块中创建一个不可见的不同 Form1 实例,然后您尝试执行访问 class

  2. 中的某些方法
  3. 如您所料,跨线程问题。您正在尝试从 UI 线程

  4. 以外的另一个线程上下文中写入

查看下面的代码来实现这一点。请记住,您可以创建 Singleton Form 或找到另一种方法来访问 Form1

的实例
  public class HostingAPI

   {
        private NancyHost hostNancy;

        private string hostUrl;

        public HostingAPI()
        {
        }

        public void Start()
        {
            var hostConfig = new HostConfiguration
            {
                UrlReservations = new UrlReservations
                {
                    CreateAutomatically = true
                },
            };

            //hostUrl = ConfigModule.ModuleAddress;

            if (hostUrl == null) hostUrl = "http://localhost:5005";

            hostNancy = new NancyHost(hostConfig,new Uri(hostUrl));

            hostNancy.Start();

        }

        public void Stop()
        {
            hostNancy.Stop();
        }
    }

public partial class Form1 : Form
{
    delegate void SetTextCallback(string text);
    public static Form1 Instance;
    public Form1(bool test)
    {
        InitializeComponent();

        textBox1.Text += "Apps Method " + Environment.NewLine;
        Instance = this;

    }   

    private void button1_Click(object sender, EventArgs e)
    {
        HostingAPI s = new HostingAPI();
        s.Start();
        textBox1.Text += "Api Running" + Environment.NewLine;
    }
    public void startTestAPI()
    {
        SetText("Api Worked" + Environment.NewLine);
    }

    private void SetText(string text)
    {
        if (this.textBox1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox1.Text += text;
        }
    }
}


 public class ModuleCDM : NancyModule
    {
        public ModuleCDM()
        {
            try
            {
                Thread th2 = Thread.CurrentThread;
                Get["/Start"] = parameters =>
                {
                    var form1 = Form1.Instance;
                    form1.startTestAPI();
                    var feeds = new[] {"Success"};
                    return Response.AsJson(feeds);
                };
            }
            catch
            {
            }
        }
    }