You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 WPF中异步调用第三方库出现无限阻塞问题求助

WPF异步调用第三方库阻塞问题及解决方案

在基于.NET 8.0的WPF应用中,调用第三方库的异步操作时出现如下问题:将代码放在MainWindow.xaml.cs中运行流畅,但移至带有静态构造函数的独立类后,即便使用WaitAsync,操作仍会无限阻塞。

原阻塞代码

public class VirtuosoCommunication
{
    // ... 其他代码
    public static VirtuosoCommunication? Create(...)
    {
        VirtuosoCommunication vc = new VirtuosoCommunication();
        // 初始化vc的私有变量

        if (!vc.TestRead(log)) return null;
        if (!vc.TestWrite(log)) return null;

        return vc;
    }

    private bool TestRead(Log? log)
    {
        string testGraph = "...";
        Task<Graph?> task = LoadGraphFromSparqlRemoteEndpoint(testGraph, log);
            
        Graph? g = task.Result;
        return g != null;
    }

    internal async Task<Graph?> LoadGraphFromSparqlRemoteEndpoint(string graphFullName, Log? log)
    {
        Uri baseUri = new Uri(_readEndpoint ?? "");

        HttpClient client = new HttpClient();
        client.BaseAddress = baseUri;

        SparqlQueryClient sparqlQueryClient = new SparqlQueryClient(client, baseUri);

        Graph result = new Graph();
        IGraph? tmp = null;
        int offSet = 0; // 假设此处有定义limit和offSet变量
        int limit = 100;

        try
        {
            while (tmp == null || tmp.Triples.Count == limit)
            {
                string query = "construct { ?s ?p ?o } FROM <" + graphFullName + "> where {?s ?p ?o.} OFFSET " + offSet.ToString() + " LIMIT " + limit.ToString();
                Task<IGraph> task = sparqlQueryClient.QueryWithResultGraphAsync(query);
                tmp = await task.WaitAsync(TimeSpan.FromSeconds(4));

                // ... 处理tmp的逻辑
                offSet += limit;
            }
        }
        catch (Exception ex) { /* 异常处理 */ }

        return result;
    }
}

调试现象

逐行调试时,代码卡在tmp = await task.WaitAsync处;点击Visual Studio的「中断执行」按钮后,显示线程返回时将执行TestRead方法中的Graph? g = task.Result行。

修改后的代码(2024.11.25更新)

将TestRead方法修改为以下形式后,代码可正常运行,但不确定是否为符合需求的正确实现:

private bool TestRead(Log? log)
{
    string testGraph = "...";
    //Task<Graph?> task = LoadGraphFromSparqlRemoteEndpoint(testGraph, log);
    Task<Graph?> task = Task.Run<Graph?>(async() => await LoadGraphFromSparqlRemoteEndpoint(testGraph, log));

    Graph? g = task.Result;
    return g != null;
}

疑问

需求仅为SPARQL端点调用不阻塞UI,无需同时运行其他并行任务,上述修改是否为正确的实现方式?

内容的提问来源于stack exchange,提问作者Aaginor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 01:33:23