如何在C#中的单独类中的新线程上运行操作或方法? [英] How to run a operation or method on a new thread in separate class in C#?

查看:389
本文介绍了如何在C#中的单独类中的新线程上运行操作或方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!我阅读了这篇文章这里,它有一个如何使用单独的线程进行操作的示例一个类,它还有一个事件,当新线程上的操作完成时,它将报告操作完成到winform(父线程),winform将打印操作已完成到UI。但问题是这是在VB.NET中,所以我试图将这个类转换为C#,但我没有成功。所以我的问题是我如何创建一个类来运行一个运行我指定的任务的线程,我也想知道我将如何制作新生成的线程报告:A。它当前在当前操作中的进展,B。当它完成时(当进度整数达到100时),它会触发一个事件,告诉winform运行一个告诉用户操作已完成的方法。这是我到目前为止的线程类:



Hello Everyone! i read this article here and it had an example of how to do operations on a separate thread using a class, it also had an event where when the operation on the new thread completed it would report that the operation was complete to the winform(parent thread) and the winform would print that the operation was completed to the UI. But the problem is that this was in VB.NET, so i attempted to convert this class in to C# but i had no success. so my question is how do i create a class that spawns off a thread that runs a task that i specify, i also want to know how i would make that newly spawned thread report: A. Its current progress in the current operation, B. when it completes(when the progress integer reaches 100) it fires an event that tells the winform to run a method that tells the user that the operation was completed. here is what i have for the thread class so far:

using System;
using System.Speech.Synthesis;
using System.Threading;
public class ManualThread
{
    //Declares The Event That Fires When The Operation Has Completed
    public delegate void CountCompleted();

    EventArgs e = new EventArgs();
    //Declares A New Instance Of The Delegate
    public event CountCompleted CountCompletedEvent;

    //Declares the variables you will use to hold your thread objects.
    public Thread Thread1;

    #region Properties
    //This Property Will Be Set In The Winform Class
    public string TextToSpeak { get; set; }

    #endregion

    public ManualThread()
    {
        this.CountCompletedEvent += new CountCompleted(this.CountCompletedEventFiredMethod);
    }

    public void StartCounting()
    {

        //Sets the copy and count threads using the AddressOf the subroutine where
        //the thread will start.
        //The Above Comment Is For The VB Version Ignore This Comment
        Thread1 = new System.Threading.Thread(this.Count);
        Thread1.IsBackground = true;
        Thread1.Name = "Thread1";
        Thread1.Start();

    }

    private void Count()
    {
        //Declare a new instance of the SpeechSynthesizer class
        SpeechSynthesizer synth = new SpeechSynthesizer();

        //Set The Audio Output Device To The Defualt Output Device
        synth.SetOutputToDefaultAudioDevice();

        // Select a voice that matches a specific gender.
        synth.SelectVoiceByHints(VoiceGender.Female);

        // Speak The Contents Of The "TextToSpeak" Property Synchronously(Only because this will be done on a new thread).            
        synth.Speak(TextToSpeak);

        //Raise the copy status event at the end of the program loop
        CountCompletedEvent();

    }
    private void CountCompletedEventFiredMethod()
    {
        //tell the winform class to run a specific method here
        //i think this would require either a message or a Invoke call
    }
}





然后在winform类级别我宣布一个像这样的新实例:



then at the winform class level i declare a new instance like this:

ManualThread ThreadOperation = new ManualThread();



然后我什么时候想要打电话给我这样做:


then when ever i want to callit i just do this:

ThreadOperation.TextToSpeak = TB.Text;
ThreadOperation.StartCounting();





现在操作运行正常,但实际上无法报告操作已完成到winform(这是因为



now the operation runs fine but it can't actually report that the operation has completed to the winform(this is due to the fact that the

CountCompletedEvent(this, e);

给了我一个空引用异常错误,因此不会触发该事件。因此我想问两件事:

1.我将如何修复此错误.2。如果我无法修复此错误,我将如何创建一个可以生成运行一个新线程的类操作,然后在操作完成时触发一个事件。

和是的我在这里读过很多关于如何在控制台和winform应用程序上进行多线程处理的文章。但是我没有理解,但是我读到的文章(上面已经链接)我理解但正如我所说它是在VB.NET中完成的

- 更新 -

哦,我也不是很与代表或活动有经验(我认为代表们与活动有关)所以请原谅我的lac这个领域的理解。



注意:ManualThread类不是我的,但我从VB转换为C#,它是

取自上面链接的文章。



--UPDATE2--

i已经找到了如何将事件处理程序添加到 ManualThreadclass,我这样做了(我必须添加一个构造函数):

gives me a null reference exception error, and therefor doesn't fire the event. therefor i would like to ask 2 things:
1. how would i fix this error. 2. if i can't fix this error how would i make a class that can spawn a new thread that runs an operation, and then fires an event when the operation is completed.
and yes i have read many articles here on codeproject talking about how to do mutlithreading on console and winform apps. but none of them i understood, but the article i read(linked above) i understood but as i said it was done in VB.NET
--UPDATE--
oh and also i am not very experienced with delegates or events(i think delegates have something to do with events) so please excuse my lack of understanding in this area.

NOTE: The class "ManualThread" is not mine but i converted from VB into C#, and it was
taken from the article linked above.

--UPDATE2--
i have figured out how to add an event handler to the "ManualThread" class, i did it like this(i had to add a constructor):

public ManualThread()
{
    this.CountCompletedEvent += new CountCompleted(this.Test);
}



但是现在它所做的只是点燃事件......而且......没什么。
$ b $我成功解雇了这个事件我只是不知道如何让winform类到这里解雇事件所以对此有任何帮助吗?

提前感谢您的所有帮助,

MasterCodeon


but now all it does is fire the event and... and... nothing.
i am successfully firing the event i just don't know how to get the winform class to here the firing of the event so any help on that please?
thank you for all of your help in advance,
MasterCodeon

推荐答案

在C#中,你必须在调用之前验证事件是否为null。如果没有附加处理程序,它将为null。因此,您应该写:
In C#, you have to verify that the event is not null before calling it. It will be null if no handler were attached to it. Thus, you should write:
if (CountCompletedEvent != null) { CountCompletedEvent(this, e); }



此外,您应该使用BackgroundWorker,因为它将更容易使用,因为它将使用ReportProgress函数在其他方面正确处理UI线程中的报告进度。 />
如果你说的那样,你不是很实验,那么很难理解你为什么要手动进行线程处理,而框架已经有了一个组件。您甚至可以将它从工具箱中删除到表单上,只需点击几下即可设置并激活处理程序。非常,非常,非常容易使用。


Also, you should use BackgroundWorker as is it much more easier to use as it will properly handle reporting progress in the UI thread using ReportProgress function amoung other things.
If as you said, you are not very experimentes, then it is hard to understand why you want to do thread handling manually while the framework already has a component for that. You can even drop it from then toolbox onto a form and a few clicks you can set and activate handlers. Very, very, very easy to use.


首先,您可以自动翻译VB.NET和C#中的任何程序集,并保证结果。使用ILSpy,最好使用整个组件。请参阅我以前的回答:代码解释,C#到VB .NET [ ^ ]。



-SA
First of all, you can translate any assembly from VB.NET and C# automatically, with guaranteed results. It's the best to do it with the whole assembly, using ILSpy. Please see my past answer: Code Interpretation, C# to VB.NET[^].

—SA


您的另一个问题是:你将如何处理来自某个非UI线程的通知,无论是完成时的通知还是其他任何事情。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

使用Treeview扫描仪和MD5的问题 [ ^ ]。



另请参阅有关线程的更多参考资料:

如何让keydown事件在不同的操作上运行vb.net中的线程 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



-SA
Your other problem is: what you are going to do with the notification from some non-UI thread, be it notification on completion or anything else. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


这篇关于如何在C#中的单独类中的新线程上运行操作或方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆