UI线程分离解决卡顿问题

This commit is contained in:
PeterZhong 2025-06-01 16:04:38 +08:00
parent 7a3516f855
commit d58510e29c
2 changed files with 53 additions and 17 deletions

View File

@ -8,10 +8,10 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Xml;
using System.Xml.Linq;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Internal.Mapping.Locate;
using LinkToolAddin.client;
using LinkToolAddin.client.prompt;
@ -33,6 +33,7 @@ using Newtonsoft.Json.Schema.Generation;
using Tool = LinkToolAddin.host.mcp.Tool;
using LinkToolAddin.common;
using LinkToolAddin.host.llm.entity.stream;
using MessageBox = ArcGIS.Desktop.Framework.Dialogs.MessageBox;
namespace LinkToolAddin.host;
@ -300,7 +301,10 @@ public class Gateway
type = MessageType.REASON_MESSAGE,
id = (timestamp-1).ToString()
};
callback?.Invoke(reasonMessageListItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(reasonMessageListItem);
});
messageContent = chunk;
var (matched, remaining) = ExtractMatchedPart(chunk, toolPattern);
if (matched == "")
@ -316,7 +320,10 @@ public class Gateway
type = MessageType.CHAT_MESSAGE,
id = timestamp.ToString()
};
callback?.Invoke(chatMessageListItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(chatMessageListItem);
});
}
else
{
@ -352,7 +359,10 @@ public class Gateway
type = MessageType.CHAT_MESSAGE,
id = timestamp.ToString()
};
callback?.Invoke(chatMessageListItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(chatMessageListItem);
});
XElement toolUse = XElement.Parse(matched);
string fullToolName = toolUse.Element("name")?.Value;
string toolArgs = toolUse.Element("arguments")?.Value;
@ -414,7 +424,10 @@ public class Gateway
? SystemPrompt.ErrorPrompt(JsonConvert.SerializeObject(toolResponse))
: SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(toolResponse))
});
callback?.Invoke(toolMessageItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(toolMessageItem);
});
}
else if (mcpServer is StdioMcpServer)
{
@ -437,7 +450,10 @@ public class Gateway
? SystemPrompt.ErrorPrompt(JsonConvert.SerializeObject(toolResponse))
: SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(toolResponse))
});
callback?.Invoke(toolMessageItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(toolMessageItem);
});
}
else if (mcpServer is InnerMcpServer)
{
@ -477,7 +493,10 @@ public class Gateway
Role = "user",
Content = SystemPrompt.ErrorPrompt(JsonConvert.SerializeObject(toolMessageItem))
});
callback?.Invoke(toolMessageItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(toolMessageItem);
});
}
else if (innerResult is JsonRpcSuccessEntity)
{
@ -495,7 +514,10 @@ public class Gateway
Role = "user",
Content = SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(toolMessageItem))
});
callback?.Invoke(toolMessageItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(toolMessageItem);
});
}
}
}
@ -526,7 +548,10 @@ public class Gateway
content = "成功调用提示词:"+promptRequest.PromptName,
id = (timestamp+1).ToString()
};
callback?.Invoke(toolMessageItem);
Application.Current.Dispatcher.Invoke(() =>
{
callback?.Invoke(toolMessageItem);
});
}
catch (Exception e)
{

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@ -37,7 +38,7 @@ namespace LinkToolAddin.ui.dockpane
private static ILog log = LogManager.GetLogger(typeof(TestDockpaneView));
private List<string> idList = new List<string>();
private Dictionary<string,MessageListItem> messageDict = new Dictionary<string,MessageListItem>();
private ConcurrentDictionary<string,MessageListItem> messageDict = new ConcurrentDictionary<string,MessageListItem>();
public TestDockpaneView()
{
@ -197,13 +198,13 @@ namespace LinkToolAddin.ui.dockpane
log.Info(msg.content);
}
private void PromptTestButton_OnClick(object sender, RoutedEventArgs e)
private async void PromptTestButton_OnClick(object sender, RoutedEventArgs e)
{
string userPrompt = PromptTestTextBox.Text;
// model可选值qwen3-235b-a22b,qwen-max,deepseek-r1
try
{
Gateway.SendMessageStream(userPrompt,"qwen3-235b-a22b", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream);
await Task.Run(() => Gateway.SendMessageStream(userPrompt,"qwen3-235b-a22b", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream));
}
catch (Exception exception)
{
@ -211,7 +212,12 @@ namespace LinkToolAddin.ui.dockpane
}
}
public void AddReplyStream(MessageListItem msg)
public async void AddReplyStream(MessageListItem msg)
{
await Task.Run(() => ProcessReplyStream(msg));
}
private void ProcessReplyStream(MessageListItem msg)
{
string id = msg.id;
if (idList.Contains(id))
@ -221,9 +227,12 @@ namespace LinkToolAddin.ui.dockpane
else
{
idList.Add(id);
messageDict.Add(msg.id, msg);
messageDict.TryAdd(msg.id, msg);
}
ReplyTextBox.Clear();
Application.Current.Dispatcher.Invoke(() =>
{
ReplyTextBox.Clear();
});
try
{
StringBuilder builder = new StringBuilder();
@ -237,14 +246,16 @@ namespace LinkToolAddin.ui.dockpane
}
builder.AppendLine(content);
builder.AppendLine();
}
Application.Current.Dispatcher.Invoke(() =>
{
ReplyTextBox.Text = builder.ToString();
ReplyTextBox.ScrollToEnd();
}
});
}catch (Exception exception)
{
log.Error(exception.Message);
}
}
public void AddReply(MessageListItem msg)