我在线程方面的经验很少。我已阅读消息来源,但大多数利用它的完整项目非常密集,线程只是其中的一小部分,因此难以确定需要什么和不需要什么。
我的项目主要需要为API的更新发出HTTP POST请求,报告(通过回调?)并且很可能放在计时器上,或者可以根据请求多次调用。
我读过的教程只涉及基本内容而没有报告并在新的/新计算的日期上执行更多操作。即使他们这样做,几乎所有人都使用过:
Control.CheckForIllegalCrossThreadCalls = false;
当你经常引用它时,我所读到的内容并不是一个好主意。
所以我想我的问题如下:
关于学校教育,这不是与学校有关的项目,而是涉及Eve Online API系统的个人项目。 EVEMon的源代码非常紧凑,简化和开发,因此很难区分代码中的线程。如果有人可以指点检查它会有所帮助。
答案 0 :(得分:1)
Joseph Albahari在线程方面有一套很好的articles,我也发现Jon Skeet的articles非常好。
.net中有很多方法可以使用线程,但要注意,它也很容易出错:)
我个人更喜欢使用reactive extensions,它允许您将典型的异步模式转换为可观察的,并且还可以为您处理ui线程编组。
e.g。
var wr = WebRequest.Create("http://someurl");
var o = Observable
.FromAsyncPattern<WebResponse>(wr.BeginGetResponse, wr.EndGetResponse)()
.ObserveOnDispatcher()
.Subscribe(response =>
{
// do stuff with the response
},
ex =>
{
//there has been an exception
});
对于WPF / Silverlight应用程序,ObserveOnDispatcher将观察者编组回UI线程,如果这是您的首选武器,则可以使用特定的调度程序。
如果您想在请求返回之前取消,只需处理从订阅呼叫返回的IDisposable。
Rx需要一些时间来解决问题,但是一旦你这么做就会非常强大。 (我还不了解所有这些)
编辑 - 这是我在winforms应用程序中汇总的一些代码,它使用Rx读取google.com的响应:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var req = WebRequest.Create("http://www.google.com");
Observable
.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse)()
.ObserveOn(this)
.Subscribe(r =>
{
using (var s = r.GetResponseStream())
using (var reader = new StreamReader(s))
{
textBox1.Text = reader.ReadToEnd();
}
},
ex =>
{
textBox1.Text = ex.Message;
});
}
}
表单上有一个文本框,它将使用响应或异常消息更新文本...
ObserveOn调用会为您处理所有Control.Invoke的内容,并确保在订阅上运行的代码位于正确的UI线程上。
只需使用nuget为所有正确的引用安装'Rx-WinForms'包:)
答案 1 :(得分:0)
取决于您所使用的.net框架,在即将发布的c#中,Async会非常容易,
答案 2 :(得分:0)
在您的表单上的代码中,您可以做一个简单的
private void EventMethod(object sender, EventArgs e)
{
if (this.InvokeRequired)
{
BeginInvoke(new EventHandler(EventMethod), sender, e);
return;
}
//cast your args to the type you know them to be
//do stuff with e or sender
}
答案 3 :(得分:0)
你可以这样做。将定时器控件放到您的表单上,然后在勾选调用中:
public void AsynchFetchIntoListBox(ListBox listBox)
{
var wr = HttpWebRequest.Create("http://example.org");
IAsyncResult ar = null;
ar = wr.BeginGetResponse(_ =>
{
var r = wr.EndGetResponse(ar);
using (var s = new StreamReader(r.GetResponseStream()))
{
var result = s.ReadToEnd();
listBox.Invoke((Action)(() =>
listBox.Items.Add(result)));
}
} , null);
}
这只是将example.org的原始html提取到一个列表框中,但它可以是任何以基本相同的方式更新任何控件的异步查询。