【发布时间】:2015-01-29 11:58:13
【问题描述】:
我正在使用很久以前用 Visual Basic.net 编写的数据库中的导出工具。
我切换到 C# 并喜欢用 C# 重新编程,因为我积累了比以前更多的经验 :-)
我的 C# 应用程序的 UI 挂起,因为有一个大型数据库查询要做。所以我已经了解了异步编程。也尝试过线程和任务,但我无法找到解决我问题的正确方法。
这就是我所拥有的:它是一个 Windows 窗体应用程序,并且有一个创建新线程的开始按钮。
名为 Export 的方法是我在名为 actions.cs 的第二个类文件中创建的非静态方法。它是非静态的,因为该方法应该在代码中经常重复使用,但参数不同。
所以我在Form1上实例化Button_Clicked事件中的方法,并带有相应的参数:
actions KuliMon = new actions()
{
ExportPath = settings.ReadActSetting("baexport", "ExportPfad", ""),
Trennzeichen = settings.ReadGlobSetting("Trennzeichen", ";"),
ConnectionString = settings.ReadGlobSetting("Mand1_odbc", ""),
SQLFile = "kuli.sql",
ExportAktion = "kuli"
};
然后我从 Button_click 事件启动线程,如下所示:
Thread ExportThread = new Thread(KuliMon.Export);
ExportThread.Start();
这行得通。没有粘贴 GUI。但是现在问题来了。我在 actions.cs 中的方法 Export 是将 DB-Query 导出到 csv-File 中,但也应该以字符串变量的形式返回结果,然后我可以将其显示在 Form1 上的 TextBox 中。
通过阅读我发现 Invoke-Method 这一点帮助很大。在 Thread.Start() 下,我添加了以下内容:
this.Invoke((MethodInvoker)delegate
{
tx_main_t1.Text = "Hello";
});
当我点击按钮时,TextBox 会说“你好”。但不是你好,我需要在线程中运行的方法导出的返回字符串。这里的问题是如何获取带有查询结果的字符串。
在我的理解中,线程方法必须调用一个 void 方法并且不能返回一个值。
我想创建一个公共属性字符串并在 Export 中使用返回值填充字符串,如下所示:
public string results { get; set; }
我尝试过在方法导出中使用 return ReturnValue 而不是
results = ReturnValue;
然后,在 Form1 中,我尝试用 KuliMon.results 填充 TextBox,但它是空的,因为我按照我的想法创建了一个 Export 实例。
【问题讨论】:
-
您是否仅限于使用 .Net 3.5 或 4.0?或者你可以使用.Net4.5吗?在 .Net4.5 中有名为 Async 和 Await 的新关键字,它们有助于创建反应式 UI。好吧,您可以通过使用 AsyncBridge 库在 3.5 或 4.0 中使用相同的功能
-
您使用的是哪个 .NET 框架版本?另外,这是什么数据库? SQL Server?
-
创建一个带有字符串属性的对象,这个对象是你的窗口知道的。现在将这些对象提供给您的线程。做你的工作。将 Result 写入您的字符串变量并让您的线程抛出一个事件(由您的 UI 处理)。在这个处理程序中,您只需读取变量并显示它的内容。
标签: c# multithreading asynchronous task