Articles of multithreading

C#COM Cross Thread

我们正在开发一种控制科学测量设备的软件。 它提供了一个COM接口定义了几个函数来设置测量参数,并在测量数据时触发事件。 为了测试我们的软件,我正在实现该设备的模拟。 com-object运行一个循环,定期触发事件。 客户端应用程序中的另一个循环现在应该使用给定的函数设置com-simulator。 我创建了一个用于测量参数的类,在设置新测量时将对其进行实例化。 // COM-Object public class MeasurementParams { public double Param1; public double Param2; } public class COM_Sim : ICOMDevice { public MeasurementParams newMeasurement; IClient client; public int NewMeasurement() { newMeasurment = new MeasurementParam(); } public int SetParam1(double val) { // why is newMeasurement null when method is called from client […]

无需中止或挂起即可立即终止无环线程

我正在实现一个协议库。 这是一个简化的描述。 主函数中的主线程将始终检查网络流上是否有某些数据(在tcpclient中)。 让我们说响应是收到的消息,而线程是一个正在运行的线程。 thread = new Thread(new ThreadStart(function)); thread.IsBackground = true; thread.Start(); while(true){ response = receiveMessage(); if (response != null) { thread.Suspend(); //I am searching for an alternative for the line above and not thread.Abort(). thread2 = new Thread(new ThreadStart(function2)); thread2.IsBackground = true; thread2.Start(); } } 到目前为止一切顺利,在while循环中实际上有更多的消息,并且还有一个用于处理不同类型的传入消息的状态机,但这应该足够了。 (还有不仅仅是函数“function”和“function2”)。 所以无论如何这些函数在这个应用程序中看起来都不清楚,因为协议是程序员隐藏的并且意味着它是一个库。 这意味着协议将启动一些程序员定义的函数作为线程,具体取决于程序在协议中的状态。 因此,如果接收到特殊响应(例如callAnotherFunction消息),我想突然终止一个线程(此处命名为“thread”),让我们说在100毫秒内。 但是我不知道它是在一个循环内执行还是没有循环,并且在它终止之前需要多少处理。 如何在不弃用Suspend或Exceptionthrowing Abort函数的情况下停止这些线程? […]

如何在每个循环周期中一步更新进度条? C#

在C#,windows窗体中创建.net应用程序。 如何在100循环循环的每个循环中更新进度条1步? (我正在处理循环中的excel表。)进度条控件位于UI类中,该类连接到连接到自定义类(MVC模式)的控制器类。 循环在自定义类中。 我是否需要在每种方法中一直向下发送UI类实例,还是有更好的方法? 现在,循环结束后进度条会更新。 Application.doevents和.update或.refresh不起作用。

System.Windows.Forms.Timer没有触发

我想使用System.Windows.Forms.Timer来确保在我正在创建的excel插件的UI线程上触发事件。 我按如下方式构建计时器: private System.Windows.Forms.Timer _timer; private void ThisAddIn_Startup(object sender, System.EventArgs e) { Debug.WriteLine(“ThisAddIn_Startup:” + Thread.CurrentThread.ManagedThreadId); _timer = new System.Windows.Forms.Timer(); _timer.Tick += new EventHandler(TimerEventHandler); _timer.Interval = 500; } 计时器由我正在使用的库中的COM事件触发: private void OnEvent() { _timer.Start(); } 然后我希望_timer在_timer时调用以下方法: public void TimerEventHandler(object sender, EventArgs args) { _timer.Stop(); Debug.WriteLine(“Tick: ” + Thread.CurrentThread.ManagedThreadId); } 据我所知,当我在Addin线程中创建计时器时,即使它是从另一个线程启动的(在这种情况下是COM事件),它应该触发它创建的线程,即插件线程。 但是,这不会发生。 我已经在我过去编写的RTDServer实现了这个确切的机制( 如Kenny Kerr所述 ),并且它按预期工作,但此场景中的_timer永远不会_timer 。 […]

.NET线程 – HttpWebRequest BeginGetResponse + AutoResetEvent

我想知道两者中的哪种方法是更好的实现? 我需要创建一个范围在200到5秒之间的Web请求。 我需要继续执行html响应 – 所以需要在主线程上阻塞。 第一种方法 string GetResponse() { HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); IAsyncResult result = request.BeginGetResponse(null, null); using (HttpWebResponse httpResponse = (HttpWebResponse)request.EndGetResponse(result)) { using (Stream dataStream = httpResponse.GetResponseStream()) { StreamReader reader = new StreamReader(dataStream); response = reader.ReadToEnd(); } } 第二种方法 string response = string.Empty; AutoResetEvent waitHandle = null; void GetResponse(string url) { waitHandle = […]

从WPF中的后台工作者更新进度条

我正在尝试使用BackgroundWorker进行进度条前进。 最终目标是显示后台搜索的进度,但我首先想要通过简单的模拟来了解进度条。 这是代码: public MainWindow() { InitializeComponent(); worker = new BackgroundWorker(); // variable declared in the class worker.WorkerReportsProgress = true; worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); worker.RunWorkerCompleted += worker_RunWorkerCompleted; } private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { this.Title += ” DONE”; } private void worker_DoWork(object sender, DoWorkEventArgs e) { for(int j = 0; […]

使用不带Invoke的MethodInvoker

我现在正在编写GUI应用程序一段时间,我总是使用一个方法是使用MethodInvoker + lambda函数来进行跨线程访问。 从示例中我发现我总是看到这样的东西: 版本1 if (InvokeRequired) { Invoke(new MethodInvoker(() => { Label1.Text = “Foobar”; }); } else { Label1.Text = “Foobar”; } 然而,这会导致代码重复 – >对我来说是主要的坏人。 那有什么不对呢? 版本2 MethodInvoker updateText = new MethodInvoker(() => { Label1.Text = “Foobar”; }); if (InvokeRequired) { Invoke(updateText); } else { updateText(); } 现在我将function捆绑在一个变量中,并在适当时使用Invoke或函数指针调用它。 版本2的性能更差吗? 或者我使用匿名函数是不好的做法?

C#在线程之间编组COM对象

我对C#marshal在线程之间是否有COM对象感到非常困惑。 为此,我有一个应用程序,它以任务并行方式加载一组文件。 我正在使用StaTaskScehduler使用COM对象加载文件。 加载COM对象后,我将对象存储在中央列表中。 然后,我再次使用STATaskScheduler尝试对此数据执行一些处理。 但是在这一点上我遇到了一个问题。 我收到如下例外情况: An unhandled exception of type ‘System.Runtime.InteropServices.InvalidComObjectException’ occurred in MadCat.exe Additional information: COM object that has been separated from its underlying RCW cannot be used 现在我的理解是我收到此错误,因为该对象尚未编组到新线程中。 我以为这是C#为你做的事情? 如何在一个线程中创建一个公寓线程COM对象,然后从另一个线程使用它? 我在这里吠叫错了吗? 我甚至不能使用Sta公寓作为我的主题吗? 我可以保证对象永远不会同时从多个线程访问。 任何想法都非常感激。 编辑 :COM对象定义如下: [ coclass, threading( apartment ), vi_progid( [Namespace.Class] ), progid( [Namespace.Class].6 ), version( 6.0 ), uuid( […]

多个线程在等待一个事件?

我想要的是AutoResetEvent的等效,多个线程可以等待,所有都在设置时恢复。 我知道这可以通过为每个线程设置一个AutoResetEvent并设置每个线程来实现 – 但是有更简单的方法吗? 一种不依赖于事件句柄数组的方法? 有效的(我认为)我希望能够做到这一点: private volatile string state; private MultiEventHandle stateChanged = new MultiEventHandle(); public void WaitForBlob() { while (true) { object saved = stateChanged.Current; // some sentinel value if (state == “Blob”) break; stateChanged.WaitTilNot(saved); // wait til sentinel value != “current” } } public void SetBlob() { state = “Blob”; stateChanged.Change(); // […]

我需要调用TcpListener.Stop()吗?

我将此代码放在一个单独的线程(Task)中,该线程在应用程序启动时首先运行,并且在应用程序关闭之前不应该结束: TcpListener tcpListener = new TcpListener(IPAddress.Any, port); tcpListener.Start(); while (true) { TcpClient client = tcpListener.AcceptTcpClient(); Task.Factory.StartNew(HandleClientCommunication, client); } 在这种情况下是否需要调用tcpListener.Stop() ? 这个线程在应用程序的整个持续时间内运行,如果我确实需要调用它,我会在哪里这样做? 侦听器是此线程的本地。 我有一个while (appRunning)循环并在FormClosing事件中将appRunning设置为false, while (true)不是有一个while (true)循环吗? 然后在while循环后我可以调用tcpListener.Stop() 。 但是,甚至需要调用TcpListener.Stop()因为应用程序已经关闭了,因为我正在使用Tasks,所以进程也会结束?