【发布时间】:2022-02-20 10:37:49
【问题描述】:
我正在尝试从 VB 切换。 Net 到 C#(.Net 框架和 .Net &)所以我开始“翻译”一些我很常用的函数。但是我遇到了一些问题(我对基于 C 的语言的线索为零)。
所以,这是我多年来使用的有效 VB .Net 函数,当我从不同的线程、任务等调用控制时,它是一个简单的跨线程解决方案:
Imports System.Linq.Expressions
Imports System.Runtime.CompilerServices
Module Module1
Private Delegate Sub InvokeThreadSafeMethodDelegate(ByVal Cnt As Control, ByVal Mtd As Expression(Of Action))
Private Delegate Function InvokeThreadSafeFunctionDelegate(Of T)(ByVal Cnt As Control, ByVal Fnc As Expression(Of Func(Of T))) As T
<Extension()>
Public Sub InvokeThreadSafeMethod(ByVal Cnt As Control, ByVal Mtd As Expression(Of Action))
If (Cnt.InvokeRequired) Then
Dim Dlg = New InvokeThreadSafeMethodDelegate(AddressOf InvokeThreadSafeMethod)
Cnt.Invoke(Dlg, Cnt, Mtd)
Else
Mtd.Compile().DynamicInvoke()
End If
End Sub
<Extension()>
Public Function InvokeThreadSafeFunction(Of T)(ByVal Cnt As Control, ByVal Fnc As Expression(Of Func(Of T))) As T
If (Cnt.InvokeRequired) Then
Dim Dlg = New InvokeThreadSafeFunctionDelegate(Of T)(AddressOf InvokeThreadSafeFunction)
Return DirectCast(Cnt.Invoke(Dlg, Cnt, Fnc), T)
Else
Return DirectCast(Fnc.Compile().DynamicInvoke(), T)
End If
End Function
End Module
我都这样称呼他们:
Me.Label1.InvokeThreadSafeMethod(Sub() Me.Label1.text = "Test")
Dim X as String = Me.Label1.InvokeThreadSafeFunction(Function() Me.Label1.text)
将它翻译成 C# 后,我得到了这个:
using System.Linq.Expressions;
internal static class Cls_Comune
{
private delegate void InvokeThreadSafeMethodDelegate(Control C, Expression<Action> M);
private delegate T InvokeThreadSafeFunctionDelegate<T>(Control C, Expression<Func<T>> F);
public static void InvocaMetodoSicuro(this Control C, Expression<Action> M)
{
if (C.InvokeRequired)
{
var D = new InvokeThreadSafeMethodDelegate(InvocaMetodoSicuro);
C.Invoke(D, C, M);
}
else
M.Compile().DynamicInvoke();
}
public static T InvocaFunzioneSicuro<T>(this Control C, Expression<Func<T>> F)
{
if (C.InvokeRequired)
{
var D = new InvokeThreadSafeFunctionDelegate<T>(InvocaFunzioneSicuro);
return (T)C.Invoke(D, C, F);
}
else
return (T)F.Compile().DynamicInvoke();
}
}
在这里,在return (T)F.Compile().DynamicInvoke(); 这一行中,我收到关于 Null 变量转换的错误。在 VB .Net 中,我使用了 C# 中似乎不存在的 Directcast。
但主要问题是,我怎么能打电话给他们?因此,给我 2 个不同的错误:
private async void Naviga(string strLnk)
{
await Task.Run(void () =>
{
Txt_Stato.InvocaMetodoSicuro(() => Txt_Stato.Text = "Test");
WW2.InvocaMetodoSicuro(() => WW2.Source = new System.Uri(strLnk, UriKind.Absolute));
string str = WW2.InvocaFunzioneSicuro(() => WW2.Source.ToString());
}
);
}
在任务中,第一行 (Txt_Stato) 给我“InvocaMetodoSicuro 不是 ToolStripLabel 的一部分”。因为它不能从 stati 类中获取扩展名。第二行(WW2 是 WebView2)给我“表达式树可能不包含赋值运算符”。 第三行(字符串 str...)没有给我任何错误,但我不知道是否有效,因为静态类中的“空错误”导致调试无法启动。
再次,我正在尝试通过自学从 VB .Net 切换到 C#,并且我想转换一些我在 VB .Net 中拥有的有用功能。因此,如果 C# 是一团糟,请认为我 2 小时前才开始使用它进行编码。 那么,代码有什么问题呢?
【问题讨论】:
-
以下内容可能会有所帮助:stackoverflow.com/questions/8983137/…
-
@user9938 是的,谢谢。这有助于我修复第一个函数,即我发送控件和 void 的函数,但不是第二个函数,其中必须是函数而不是 void。为了让您更好地理解,在 Tanks 中,前 2 个代码(
Txt_Stato和WW2)现在有效,但string str = ...无效,因为它不是空的。
标签: c# vb.net multithreading async-await task