c# - 如何进行C#异步编程?

标签 c# multithreading asynchronous task

我正在研究我很久以前用 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 中的导出方法是将 DB-Query 导出到 csv-File,但也应该以字符串变量的形式返回结果,然后我可以在 Form1 上的 TextBox 中显示该结果。

通过阅读一些资料,我发现 Invoke-Method 对我有很大帮助。在 Thread.Start() 下,我添加了以下内容:

this.Invoke((MethodInvoker)delegate
        {
             tx_main_t1.Text = "Hello";
        });

当我单击按钮时,文本框会显示“你好”。但是我需要的不是 hello,而是在线程中运行的方法 Export 中的 Return 字符串。问题是如何获取包含查询结果的字符串。

根据我的理解,线程方法必须调用一个 void 方法并且不能返回值。

我想创建一个公共(public)属性字符串,并用这样的返回值填充 Export 中的字符串:

public string results { get; set; }

我试过在 Method Export 中没有使用 return ReturnValue

results = ReturnValue;

然后在 Form1 中,我尝试用 KuliMon.results 填充 TextBox,但它是空的,因为我已经按照我的想法创建了一个 Export 实例。

最佳答案

数据库查询和写入文件都是 I/O 绑定(bind)操作,因此它们非常适合 asyncawait

首先,您将定义 KuliMon.Export 的异步版本:

async Task<string> ExportAsync()
{
  var data = await myQuery.ToListAsync();

  await myStream.WriteAsync(...);

  return results;
}

例如,您可以使用 Entity Framework 6 for asynchronous query support .

然后您可以从您的 UI 中这样调用它:

async void button1_Clicked(...)
{
  TextBox1.Text = await myInstance.ExportAsync();
}

如果您出于某种原因不能使用异步数据库查询(例如,我认为 Oracle 目前不支持它们),那么您可以使用调用同步 API 的后台线程。请注意,Task.RunThreadBackgroundWorker 的现代替代品:

string Export();
...
async void button1_Clicked(...)
{
  TextBox1.Text = await Task.Run(() => myInstance.Export());
}

关于c# - 如何进行C#异步编程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28214218/

相关文章:

android - Runnable 可以返回一个值吗?

java - 为什么 hibernate 主线程会改变 Java 中正在运行的其他线程的行为?

c - 简单的 C pthread 测试程序在执行期间挂起

c# - 上限双两位数点后

c# - 当尝试从 WCF 服务支持双 LAN 时,WCF 内部异常消息 "A registration already exists for URI ' net.tcp ://. .. .' "

c# - 单点触控 : Sending/Receiving NSData Though GameKit

c++ - 在C++中收到输入时如何停止执行异步功能

c# - 通用 Windows 平台中的 System.Xml.XPath

javascript - 如何在 AngularJS 中中断/返回 Angular 异步调用

c# - 使用异步等待时出现意外结果