当我在使用Visual Studio 2015时键入C#文件时,它会间歇性地挂起一次,最多可持续30秒。这种情况是随机发生的,没有明确的原因(没有高CPU使用率,或者没有在单击按钮后出现)。
当多个编辑器被撕下时,在窗口之间单击也需要很长时间。
答案 0 :(得分:1)
总的来说,我认为问题可能与DDE / SendMessage(HWND_BROADCAST, …)
有关。快速测试程序确认,发送到HWND_BROADCAST
的消息将使呼叫者挂掉。
要弄清楚罪魁祸首是什么,我在下面编写了测试程序-在我的情况下,该程序将手指指向OfficeC2RClient
。终止OfficeC2RClient
进程可以解决此问题。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SendMessageTest
{
class Program
{
private static readonly IntPtr
HWND_BROADCAST = (IntPtr)65535;
private const int
WM_NULL = 0;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam, int fuFlags, int uTimeout, out IntPtr result);
protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int processId);
protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
{
int size = GetWindowTextLength(hWnd);
if (size++ > 0 && IsWindowVisible(hWnd))
{
StringBuilder sb = new StringBuilder(size);
GetWindowText(hWnd, sb, size);
Console.WriteLine(sb.ToString());
}
return true;
}
static void Main(string[] args)
{
LoopSendMessage();
}
private static void BroadcastMessage()
{
while (true)
{
var stp = Stopwatch.StartNew();
SendMessage(HWND_BROADCAST, WM_NULL, IntPtr.Zero, IntPtr.Zero);
stp.Stop();
Console.WriteLine("Duration = {0}", stp.Elapsed);
if (stp.ElapsedMilliseconds > 250)
{
Debugger.Break();
}
Thread.Sleep(100);
}
}
private static void LoopSendMessage()
{
if (EnumWindows(LoopSendMessage_Call, IntPtr.Zero))
{
Console.WriteLine("Completed");
}
else
{
Console.WriteLine("Failed");
}
Console.ReadLine();
}
private static bool LoopSendMessage_Call(IntPtr hWnd, IntPtr lParam)
{
IntPtr _unused;
var stp = Stopwatch.StartNew();
if (SendMessageTimeout(hWnd, WM_NULL, IntPtr.Zero, IntPtr.Zero, 1, 5000, out _unused) == IntPtr.Zero)
{
if (stp.ElapsedMilliseconds > 5)
{
if (Marshal.GetLastWin32Error() == 1460)
{
Console.WriteLine($"HWND {hWnd.ToString("x8")} timed out after {stp.ElapsedMilliseconds:n0}ms");
}
else
{
Console.WriteLine($"HWND {hWnd.ToString("x8")} failed after {stp.ElapsedMilliseconds:n0}ms");
}
int pid;
GetWindowThreadProcessId(hWnd, out pid);
var proc = Process.GetProcessById(pid);
Console.WriteLine($" {proc.Id} {proc.ProcessName}");
}
}
else if (stp.ElapsedMilliseconds > 250)
{
Console.WriteLine($"HWND {hWnd.ToString("x8")} took {stp.ElapsedMilliseconds:n0}ms");
}
return true;
}
}
}