Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确捕获异步任务?_C#_Async Await_Try Catch - Fatal编程技术网

C# 如何正确捕获异步任务?

C# 如何正确捕获异步任务?,c#,async-await,try-catch,C#,Async Await,Try Catch,我想知道为什么这个Click事件中的异常没有被捕获?除了向用户显示进程状态的statusLabel之外,代码中没有什么特别之处myDataTable是一个局部变量;目标是将结果分配给它 GetDataTable是否也必须是异步的 public DataTable GetDataTable(string connectionString, string cmdText) { DataTable dt = new DataTable(); using (SqlConnection c

我想知道为什么这个
Click
事件中的异常没有被捕获?除了向用户显示进程状态的
statusLabel
之外,代码中没有什么特别之处
myDataTable
是一个局部变量;目标是将结果分配给它

GetDataTable
是否也必须是异步的

public DataTable GetDataTable(string connectionString, string cmdText)
{
    DataTable dt = new DataTable();
    using (SqlConnection conn = new SqlConnection(connectionString)) {
        using (SqlCommand comm = new SqlCommand(cmdText, conn)) {
            conn.Open();
            dt.Load(comm.ExecuteReader);
            return dt;
        }
    }
}

private async void Button1_Click(object sender, EventArgs e)
{
    try {
        statusLabel.Text = "Processing...";

        Task<DataTable> dtTask = Task.Run(() => GetDataTable(connectionString, commandText));
        await dtTask;
        myDataTable = dtTask.Result;

        statusLabel.Text = "Done!";
    } catch (Exception ex) {
        MessageBox.Show("Error");
    }
}

感谢大家的耐心

我相信你想要的答案是:

我假设“Button1\u Click”方法是“async void”?:

private async void Button1_Click(object sender, EventArgs e)
{
    ...
}

不要使用
Task.Run
将同步方法转换为异步方法,而是使用
ExecuteReaderAsync
以真正异步加载数据。之后,您的代码变得简单得多:

public async Task<DataTable> GetDataTable(string connectionString, string cmdText)
{
    DataTable dt = new DataTable();
    using (SqlConnection conn = new SqlConnection(connectionString)) {
        using (SqlCommand comm = new SqlCommand(cmdText, conn)) {
            conn.Open();
            var reader=await comm.ExecuteReaderAsync();
            dt.Load(reader);
            return dt;
        }
    }
}

private async void Button1_Click(object sender, EventArgs e)
{
    try {
        statusLabel.Text = "Processing...";

        myDataTable = await GetDataTable(connectionString, commandText);

        statusLabel.Text = "Done!";
    } catch (Exception ex) {
        MessageBox.Show("Error");
    }
}
之后,设置
myDataTable
变量只需要使用
wait

myDataTable = await GetDataTable(connectionString, commandText);

您正在使用结果属性。。最好不要使用任务。我假设问题是在非异步方法上使用wait。我可以准确地分析发生了什么(因此是评论而不是回答)。您可以完全删除该行,也可以使用GetAwaiter().GetResult()代替该行和下面的一行。如G-Man所说,如果您正在同步等待结果,请参见和或。@G-Man在分配
myDataTable=dtTask.result
之前,他正在等待
dtTask
。所以它仍然是异步的。本质上与
myDataTable=wait dtTask
@AwonDanag相同,我无法在测试代码中重现您的问题。您确定
GetDataTable()
正在抛出异常,还是没有接受它?如果出于测试目的,您替换
GetDataTable()
的内容只是抛出一个异常,会发生什么?是的,我错过了这个。它应该是异步的。酷!正如我在编辑中所说,我使用了
Open()
ExecuteReader()
的异步对应项,结果似乎很好。。。我知道您只使用了ExecuteReaderAsync()-会有区别吗?
var reader=await comm.ExecuteReaderAsync();
dt.Load(reader);
return dt;
myDataTable = await GetDataTable(connectionString, commandText);