gpt4 book ai didi

C# - 后台 worker ?

转载 作者:太空狗 更新时间:2023-10-30 01:09:19 30 4
gpt4 key购买 nike

我有一个相当复杂的程序,所以我不会在这里转储整个程序。这是一个简化版本:

class Report {
private BackgroundWorker worker;

public Report(BackgroundWorker bgWorker, /* other variables, etc */) {
// other initializations, etc
worker = bgWorker;
}

private void SomeCalculations() {
// In this function, I'm doing things which may cause fatal errors.
// Example: I'm connecting to a database. If the connection fails,
// I need to quit and have my background worker report the error
}
}


// In the GUI WinForm app:
// using statements, etc.
using Report;

namespace ReportingService {
public partial class ReportingService : Form {

// My background worker
BackgroundWorker theWorker = new BackgroundWorker() {
WorkerReportsProgress = true
};

// The progress changed event
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
// e.UserState and e.ProgressPercentage on some labels, etc.
}

// The do work event for the worker, runs the number crunching algorithms in SomeCalculations();
void worker_DoWork(object sender, DoWorkEventArgs e) {
Report aReport = e.Argument as Report;

aReport.SomeCalculations();
}

// The completed event, where all my trouble is. I don't know how to retrieve the error,
// or where it originates from.
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
// How, exactly, do I get this error message? Who provides it? How?
if (e.Error != null) {
MessageBox.Show("Error: " + (e.Error as Exception).ToString());
}
else if (e.Cancelled) {
MessageBox.Show("Canceled");
}
// operation succeeded
else {
MessageBox.Show("Success");
}
}

// Initialization of the forml, etc
public ReportingService() {
InitializeComponent();

theWorker.ProgressChanged += worker_ProgressChanged;
theWorker.DoWork += worker_DoWork;
theWorker.RunWorkerCompleted += worker_RunWorkerCompleted;
}

// A button that the user clicks to execute the number crunching algorithm
private void sumButton_Click(object sender, EventArgs e) {
Report myReport = new Report(theWorker, /* some other variables, etc */)
theWorker.RunWorkerAsync(myReport);
}
}
}

这是我的逻辑,如果我以错误的方式进行此操作,请纠正我:

  1. 我从 GUI 中抽象出该类,因为它大约有 2000 行,并且需要成为它自己的自包含对象。

  2. 我将后台工作人员传递到我的类(class),以便我可以报告我的数字处理进度。

我不知道如何做的是让后台工作人员知道我的类(class)内部发生了错误。为了获得 RunWorkerCompleted 参数作为异常,我的 try/catch block 需要去哪里,我应该在 catch block 中做什么?

感谢您的帮助!

编辑:

我尝试了以下方法来测试错误处理:

请记住,我损坏了我的数据库连接字符串是为了故意接收一条错误消息。

在我的类里面我这样做:

// My number crunching algorithm contained within my class calls a function which does this:

// try {
using (SqlConnection c = GetConnection()) { // note: I've corrupted the connection string on purpose
c.Open(); // I get the exception thrown here
using (SqlCommand queryCommand = new SqlCommand(query, c)) { /* Loop over query, etc. */ }
c.Close();
}
// } catch (Exception e) { }

1.根据我的理解,未处理的异常被转换为 RunWorkerCompletedEventArgsError 部分?当我尝试这个时,我得到以下信息:

// In my winform application I initialize my background worker with these events:

void gapBW_DoWork(object sender, DoWorkEventArgs e) {
Report aReport = e.Argument as Report;
Report.Initialize(); // takes ~1 minute, throws SQL exception
Report.GenerateData(); // takes around ~2 minutes, throws file IO exceptions
}

void gapBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error != null) { // I can't get this to trigger, How does this error get set?
MessageBox.Show("Error: " + (e.Error as Exception).ToString());
}
else if (e.Cancelled) {
MessageBox.Show("Canceled: " + (e.Result).ToString());
}
else {
MessageBox.Show("Success");
}
}

Visual Studio 说我的应用程序因未处理的异常而因 c.Open() 而阻塞。

2。当我在我的 DoWork 函数中放置一个 try/catch block 时:

void gapBW_DoWork(object sender, DoWorkEventArgs e) {
try {
Report aReport = e.Argument as Report;
aReport.Initialize(); // throws SQL exceptions
aReport.GenerateData(); // throws IO file exceptions
}
catch (Exception except) {
e.Cancel = true;
e.Result = except.Message.ToString();
}
}

void gapBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error != null) { // I can't get this to trigger, How does this error get set?
MessageBox.Show("Error: " + (e.Error as Exception).ToString());
}
else if (e.Cancelled) {
MessageBox.Show("Canceled: " + (e.Result).ToString());
}
else {
MessageBox.Show("Success");
}
}

我在自动生成的 Application.Run(new ReportingService()); 行的 Program.cs 中收到 TargetInvocationException was unhandled。我在 RunWorkerCompleted 上放置了一个断点,可以看到 e.Cancelled = true、e.Error = null 和 e.UserState = null。 e.Cancelled 中包含的消息只是“操作已被取消”。我想我正在从 e.Result 的无效转换中接收到 TargetInvocationException(因为它为 null)。不过,我想知道的是,为什么 e.Error 仍然为 null 而 e.Canceled 不包含有关为什么操作被取消的任何有用信息?

3。当我尝试在异常捕获时从 DoWork 中设置 e.Canceled = true; 时,我设法触发了我的 中的 else if (e.Cancelled) { 行>RunWorkerCompleted 函数。我以为这是为请求取消作业的用户保留的?我是否从根本上误解了后台工作人员的工作方式?

最佳答案

我尝试了这个小测试程序,它按预期工作:

static void Main(string[] args)
{
var worker = new BackgroundWorker();

worker.DoWork += (sender, e) => { throw new ArgumentException(); };
worker.RunWorkerCompleted += (sender, e) => Console.WriteLine(e.Error.Message);
worker.RunWorkerAsync();

Console.ReadKey();
}

但是当我在调试器中运行该程序时,我还在 throw 语句中收到了有关未处理异常的消息。但我只是再次按下 F5,它继续没有任何问题。

关于C# - 后台 worker ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7115058/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com