如何从 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 个问题。
您从 Form1 实例启动主机 api 服务,然后在 Nancy 模块中创建一个不可见的不同 Form1 实例,然后您尝试执行访问 class
中的某些方法
如您所料,跨线程问题。您正在尝试从 UI 线程
以外的另一个线程上下文中写入
查看下面的代码来实现这一点。请记住,您可以创建 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
{
}
}
}
我在我的 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 个问题。
您从 Form1 实例启动主机 api 服务,然后在 Nancy 模块中创建一个不可见的不同 Form1 实例,然后您尝试执行访问 class
中的某些方法
如您所料,跨线程问题。您正在尝试从 UI 线程
以外的另一个线程上下文中写入
查看下面的代码来实现这一点。请记住,您可以创建 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
{
}
}
}