如何从以Nancyfx开始的工作线程在主线程中运行?C#

如何从以Nancyfx开始的工作线程在主线程中运行?C#,c#,.net,multithreading,winforms,nancy,C#,.net,Multithreading,Winforms,Nancy,我在winform应用程序中使用nancyfx时遇到问题(我制作了winform应用程序并在应用程序中使用了nancyfx),因此我可以使用一些API url在winform中进行更改,而无需额外的服务器或服务(因为我在winform应用程序中附加了nancy) 这是我的Form1.cs public partial class Form1 : Form { public Form1(bool test) { InitializeComponent();

我在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工作”)。我注意到这是因为Nancyfx在有API调用时创建了另一个线程,我可以使用invoke/begininvoke,因为!invokererequired总是带有值false。那么,当我调用API时,如何访问主线程或其他解决方案来更新UI呢


谢谢你这里有两个问题

  • 您从Form1实例启动HostAPI服务,然后在模块中创建一个不可见的不同Form1实例,并尝试访问该类中的某些方法

  • 正如您正确猜测的那样,跨线程问题。您正在尝试从UI线程以外的其他线程上下文进行写入

  • 请看下面的代码以实现这一点。请记住,您可以创建Singleton表单或找到其他方法来访问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
                {
                }
            }
        }