假设在这个帖子中有建设性的批评Thread-safe events - is this a "clean" way?我坐下来试图在多线程的整个主题中读到我。
以下是一些具有相同基本问题的代码:这是使用事件创建非冻结UI的既定方法吗?
public partial class Form1 : Form
{
public delegate void MyThreadUpdateHandler(string s);
public event MyThreadUpdateHandler MyThreadUpdate;
System.Threading.Thread MyThread;
public Form1()
{
InitializeComponent();
}
void DoTheCount()
{
int a = 0;
while (a < int.MaxValue)
{
if (a % 1000000 == 0)
{
this.MyThreadUpdate(a.ToString());
}
a++;
}
}
private void Form1_MyThreadUpdate(string s)
{
this.lblEvent.Invoke((MethodInvoker) delegate ()
{
lblEvent.Text = s;
});
}
private void btnStartThread_Click(object sender, EventArgs e)
{
MyThreadUpdate += Form1_MyThreadUpdate;
if (MyThread == null)
MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(DoTheCount));
lblStatus.Text = "Starting thread";
if (MyThread.ThreadState == System.Threading.ThreadState.Unstarted)
MyThread.Start();
}
private void btnAbortThread_Click(object sender, EventArgs e)
{
MyThread.Abort();
}
}
然而,还有一些我还没有得到的东西。为什么有些例子使用像这样的Program()? http://www.codeproject.com/Articles/667298/Using-ThreadStaticAttribute
谢谢:)
答案 0 :(得分:3)
然而,还有一些我还没有得到的东西。为什么有一些例子 使用像这样的程序()? http://www.codeproject.com/Articles/667298/Using-ThreadStaticAttribute
代码是
static void Main(string[] args)
{
Program prog = new Program();
//define the threads
Thread thread1 = new Thread(new ThreadStart(prog.ThreadFunc1));
Thread thread2 = new Thread(new ThreadStart(prog.ThreadFunc2));
这允许开发人员调用实例函数public void ThreadFunc1()
&amp; public void ThreadFunc2()
来自静态功能 - static void Main(string[] args)
更新1
创建非冻结UI的既定方法是在单独的线程上进行所有耗时的活动。将调用UI线程仅编组以更新到它。 您实施的内容遵循相同的想法。
我想提一点,虽然它与冻结UI没有任何关系。
而不是System.Threading.Thread
,请使用ThreadPool
。
Task
,BackgroundWorker
,System.Threading.Timer
,Asynchronous Programming Model
都使用来自ThreadPool
的帖子。或者您也可以使用ThreadPool.QueueUserWorkItem
有一个非常特殊的情况,一个人应该使用System.Threading.Thread
而不是来自ThreadPool
的帖子
答案 1 :(得分:2)
首先,请允许我说,我为您感到遗憾,尝试使用旧版库。
好。您有资格获得我在.net
中使用线程的几个原因之一长时间运行旧版库
现在,阅读您之前的代码,我觉得您想将Rx.Net用于项目。
我首先要为您的库创建一个IObservable
。
public static class LibraryHelper
{
public static IObservable<EventPattern<StatusChangedEventArg>> StatusObservable(this ComLibrary com)
{
return Observable.FromEventPattern<EventHandler<StatusChangedEventArg>, StatusChangedEventArg>(x => com.FooEvent +=x, x => com.FooEvent -= x);
}
}
这将允许您将Rx.Net与您的库一起使用,如此......
private async void btnStartThread_Click(object sender, EventArgs e)
{
ComLibary com = new ComLibray();
lblStatus.Text = "Starting thread";
// using is there to unsubscribe after the call, to prevent a memory leak.
var subscription = com.StatusObservable()
//Magic sauce
//http://stackoverflow.com/questions/7417978/how-to-get-a-winform-synchronization-context-or-schedule-on-a-winform-thread
.ObserveOn(SynchronizationContext.Current)
.Subscribe(@event => {
//Do something on the UI thread
});
using(subscription)
{
//Task.Run uses a background thread to get the data from your COM
var result = await Task.Run(()=> com.Read());
//back in UI thread. Do stuff.
}
}