将类作为新线程运行

发布于 2024-07-14 17:54:10 字数 463 浏览 8 评论 0原文

我想在新线程中开始一项工作或使用后台工作人员来执行此操作,但之前没有这样做过,并询问您应该以哪种方式执行此操作。

我的程序有一个带有文件列表的数据网格视图,每行一个文件。 我希望用户能够选择一行,然后按“开始下载”来启动下载的后台作业。 我想获取下载进度的事件。

我有一个类 clsDownload 可以处理所有事情并引发事件,但是如何实现后台工作?

我应该在类内部使用 System.ComponentModel.BackgroundWorker 还是创建一些处理此问题的包装器或使用其他线程内容?

谢谢。

编辑:我不明白如何在后台工作者中实现我的下载,任何小例子都会很好。 msdn 上的例子并没有让我走得太远。

我有一个具有 StartDownload 功能的下载类。 我应该在课堂上还是在调用者中使用后台工作者? “感觉自己很蠢”

I want to start a job in a new thread or using backgroundworker to do it but havent done that before and asking you wich way I should do it.

My program has a datagridview with a list of files, one file per row. I want the user to be able to select a row and then press "Start download" to start a background job of the download. I want to get events back of the progress of the download.

I have a class clsDownload that handles everything and raises events back but how do I implement the backgroundworking?

Should I use the System.ComponentModel.BackgroundWorker inside of the class or create some wrapper that handles this or use some other threading stuff?

Thanks.

Edit: I dont understand how to implement my download in the backgroundworker, any small example would be very nice. The example on msdn didnt get me far.

I have a download class that has a StartDownload-function. Should I use the backgroundworker IN the class or in the caller? "feeling stupid"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初见你 2024-07-21 17:54:10

如果您需要在 UI 上向用户提供反馈,我强烈建议使用 BackgroundWorkerProgressChangedRunWorkerCompleted 事件在 UI 线程上运行,因此无需进行编组,这会使您的代码更加复杂。

I'd strongly advise BackgroundWorker if you need to provide feedback to the user on the UI. The ProgressChanged and RunWorkerCompleted events are run on the UI thread, so there's no need to do marshalling, which can make your code more complex.

一梦等七年七年为一梦 2024-07-21 17:54:10

如果您只需要下载并且不需要其他异步处理,您可以只使用 WebClient 类。 尽管您已经拥有自己的课程,但这可能不是您的解决方案。

否则,您可以使用 BackgroundWorker< /a> 正如你提到的。 MSDN 页面有一个如何执行此操作的示例。

编辑:简短的故事是:

  • 您从调用者创建BackgroundWorker
  • 当您想要启动后台工作时,您可以调用BackgroundWorker.RunWorkerAsync;
  • 在 DoWork 事件处理程序中,您执行后台工作,在您的情况下,您启动下载类;
  • 当您进行后台工作时,您必须每隔一段时间检查一次 CancelationPending
  • 当您想要报告某些进度时,您需要以百分比计算并调用ReportProgress

如果您需要真正定制的东西,您可以随时创建自己的 线程

我个人会坚持使用BackgroundWorker。 它针对工作的各个阶段提供了一组很好的通知。 如果您使用Thread,您将必须自己实现这些。

我还要确保代码不会创建太多实例。 您想要限制并发下载的数量并对超过该数量的任何内容进行排队。

I you are only going to do downloading and don't need other async processing, you can just use the async methods of the WebClient class. Though since you already have your own class, that's probably not a solution for you.

Otherwise, you can use BackgroundWorker as you mentioned. The MSDN page has an example how to do it.

EDIT: The short story is:

  • You create the BackgroundWorker from the caller;
  • When you want to start the background work, you call BackgroundWorker.RunWorkerAsync;
  • in the DoWork event handler you do the background work, in your case you start your download class;
  • while you're doing the background work, you have to check every once in a while for CancelationPending;
  • when you want to report some progress, you need to calculate it in percentage and call ReportProgress.

And if you need something really customized, you can always create your own Thread.

I personally would stick with BackgroundWorker. It has a nice set of notifications for various stages of the job. If you use Thread, you will have to implement these youself.

I would also make sure the code does not create too many instances. You want to limit the number of concurent downloads and queue anything past that number.

彻夜缠绵 2024-07-21 17:54:10

我创建了几个包含BackgroundWorker 的不同类。 我通常做的是在表单上有一个 BackgroundWorker 组件,该组件将在执行作业时打开,然后将该实例传递给作业类的构造函数。

您的作业类可能如下所示:

Private m_bwMain As BackgroundWorker

Public Sub New(ByVal bwMain As BackgroundWorker)
    m_bwMain = bwMain

    'additional setup code here
End Sub

要开始作业,您可以在“开始下载”按钮的 Click 事件处理程序中执行以下操作:

lblStatus.Text = "Initializing ..."
bgwMain.RunWorkerAsync(someFileName)

我将作业类声明为当前表单的私有成员,然后在中实例化它BackgroundWorker.DoWork 事件。 从那里您可以调用您的方法来下载文件:

Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
    m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
    m_oJobEngine.DownloadFile(CStr(e.Argument))
End Sub

要向用户报告进度,您可以在主窗体中处理类引发的事件。 您只需要确保作业类对象声明具有 WithEvents 关键字。 从这些处理程序中,您可以调用BackgroundWorker 的ReportProgress 方法。 在 ReportProgress 中,您可以对 UI 进行任何所需的更改以指示进度。 这是一个例子:

Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
    bgw.ReportProgress(0, bytesTransferred)
End Sub
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
    lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
End Sub

希望这有帮助。

I've created several different classes that incorporate BackgroundWorker. What I generally do is have a BackgroundWorker component on the form that will be open when the job is being performed, then I pass that instance to the constructor of my job class.

Here is what your job class might look like:

Private m_bwMain As BackgroundWorker

Public Sub New(ByVal bwMain As BackgroundWorker)
    m_bwMain = bwMain

    'additional setup code here
End Sub

To start a job, you would do something like this in the Click event handler of your Start Download button:

lblStatus.Text = "Initializing ..."
bgwMain.RunWorkerAsync(someFileName)

I declare my job class as a private member of the current form, then instantiate it in the BackgroundWorker.DoWork event. From there you can call your method to download a file:

Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
    m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
    m_oJobEngine.DownloadFile(CStr(e.Argument))
End Sub

To report progress to the user, you can handle the events raised by your class in your main form. You just need to make sure the job class object declaration has the WithEvents keyword. From those handlers you can call the ReportProgress method of BackgroundWorker. From within ReportProgress you can make whatever changes you need to the UI to indicate progress. Here's an example:

Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
    bgw.ReportProgress(0, bytesTransferred)
End Sub
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
    lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
End Sub

Hope this helps.

月棠 2024-07-21 17:54:10

后台工作者看起来应该可以工作... MSDN 上有一个示例。

http://msdn.microsoft.com/en-us/ library/system.componentmodel.backgroundworker.aspx

或者您可以执行以下操作:

WaitCallBack workCallBack= new WaitCallBack(DownloadMethod);
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled")
{
   // Unable to Pool
}

// Work has been added to pool and will execute when possible

取决于线程需要哪些参数(如果有)。

The backgroundworker looks like it should work... There is an example on MSDN.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Or you could do something like:

WaitCallBack workCallBack= new WaitCallBack(DownloadMethod);
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled")
{
   // Unable to Pool
}

// Work has been added to pool and will execute when possible

Depends what parameters if any you need for the Thread.

夏末的微笑 2024-07-21 17:54:10

使用 clsDownload 的类(可能是您的 Form 类)应该使用 BackgroundWorker 来运行下载方法。

The class that uses clsDownload (probably your Form class) should use BackgroundWorker to run the download method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文