C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

これらの引数で呼び出されるアクセス可能なNewがないため・・

[トピック内 19 記事 (1 - 19 表示)]  << 0 >>

■83350 / inTopicNo.1)  これらの引数で呼び出されるアクセス可能なNewがないため・・
  
□投稿者/ 惹起 (1回)-(2017/03/18(Sat) 22:04:17)

分類:[.NET 全般] 



Dim sss As Task = New Task(AddressOf aaa, bbb)
sss.Start()


というようなマルチスレッドの処理を書きたいのですが
Option Strict On無しだとエラーなく実行できるのに
Option Strict Onを有りにすると、

これらの引数で呼び出されるアクセス可能なNewがないため、オーバーロードに解決に失敗しました

というエラーが出ます。


Dim menuFile As ToolStripMenuItem = New ToolStripMenuItem("test")
menuFile.DropDownItems.Add(New ToolStripMenuItem(GetBuildDateTime))
Me.MenuStrip1.Items.Add(menuFile)

というのでも同じエラーが出ます。

以下では

MultiProgram_run = New System.Threading.Thread( _
New System.Threading.ParameterizedThreadStart(AddressOf Program_runxx))

Option Strict Onでは、〜とデリゲート〜間の暗黙的な縮小変換は許可されていません。

というエラーが出ます。

これらのエラーが出ないようにするにはどうしたら良いですか?




引用返信 編集キー/
■83359 / inTopicNo.2)  Re[1]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ shu (980回)-(2017/03/19(Sun) 01:54:07)
No83350 (惹起 さん) に返信
>
>
> Dim sss As Task = New Task(AddressOf aaa, bbb)
> sss.Start()
>
>
> というようなマルチスレッドの処理を書きたいのですが
> Option Strict On無しだとエラーなく実行できるのに
> Option Strict Onを有りにすると、
>
> これらの引数で呼び出されるアクセス可能なNewがないため、オーバーロードに解決に失敗しました
>
> というエラーが出ます。

Taskのコンストラクタのうち引数が2つのものは
https://msdn.microsoft.com/ja-jp/library/system.threading.tasks.task(v=vs.110).aspx
にあるように
Task(Action,&#8194;CancellationToken)
Task(Action,&#8194;TaskCreationOptions)
Task(Action<Object>,&#8194;Object)
のどれかです。
提示されたコードで
aaa,bbbがこの型にマッチしていないとこのエラーが発生します。



>
>
> Dim menuFile As ToolStripMenuItem = New ToolStripMenuItem("test")
> menuFile.DropDownItems.Add(New ToolStripMenuItem(GetBuildDateTime))
> Me.MenuStrip1.Items.Add(menuFile)
>
> というのでも同じエラーが出ます。
同じようにToolStripMenuItemのコンストラクタで引数1つのものは
https://msdn.microsoft.com/ja-jp/library/system.windows.forms.toolstripmenuitem(v=vs.110).aspx
にあるように
ToolStripMenuItem(String)
だけですので
GetBuildDateTimeがString型でなければこのエラーが発生します。





> 以下では
>
> MultiProgram_run = New System.Threading.Thread( _
> New System.Threading.ParameterizedThreadStart(AddressOf Program_runxx))
>
> Option Strict Onでは、〜とデリゲート〜間の暗黙的な縮小変換は許可されていません。
>
> というエラーが出ます。
https://msdn.microsoft.com/ja-jp/library/system.threading.parameterizedthreadstart(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
にあるようにParameterizedThreadStartはobject型の引数を1つもつSubですのでProgram_runxxがそれに相当していないと思われます。
また、このリンク先にあるようにこの記述は
Thread(AddressOf Program_runxx)と書けます。


>
> これらのエラーが出ないようにするにはどうしたら良いですか?
>
型があうようにしてください。
引用返信 編集キー/
■83360 / inTopicNo.3)  Re[2]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (2回)-(2017/03/19(Sun) 10:19:49)



ありがとうございます。

うまくいきました。

ところで、
Taskでクラス変数を渡したい場合には、

Sub aaa(ByVal bbb As Object)

ccc = DirectCast(bbb, Class_Na,e)

End Sub


のようにして、オブジェクト変数として渡してから
そのクラスの変数にキャストして使うしかないのでしょうか?
これが一般的な用法でしょうか?



あと、以下のようにWScript.Shellを使いたい場合には、
遅延バインディングは使用できません、
とのエラーが出ますが、これはどのように回避すれば良いでしょうか?


Dim objWSH As Object = CreateObject("WScript.Shell")

Dim qqq As String = objWSH.SpecialFolders("Desktop") & "\" & filename




引用返信 編集キー/
■83364 / inTopicNo.4)  Re[3]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 魔界の仮面弁士 (1202回)-(2017/03/19(Sun) 14:08:07)
No83360 (惹起 さん) に返信
> ccc = DirectCast(bbb, Class_Na,e)
> これが一般的な用法でしょうか?

引数が 3 つ渡されているのは一般的では無いですね。(^_^;)
もしかして、
 Dim ccc = DirectCast(bbb, Class_Name)
の間違いでしょうか。


Sub aaa(x As Object) ではなく
Sub aaa(x As Class_Name) に対して渡したいのなら、
 Dim ss As New Task(Sub() aaa(bbb))
という手もあります。今回の要件に合うかは分かりませんが。


> Dim objWSH As Object = CreateObject("WScript.Shell")
> Dim qqq As String = objWSH.SpecialFolders("Desktop") & "\" & filename

わざわざ COM オブジェクトを使わずとも、この程度なら
 Dim qqq = System.IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, filename)
もしくは
 Dim qqq = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), filename)
で十分だと思いますよ。

WshShell オブジェクトを使うとなると、使用後に
System.Runtime.InteropServices.Marshal.ReleaseComObject メソッドでの
解放処理も必要になってくるでしょうし、あまりお奨めしません。


> とのエラーが出ますが、これはどのように回避すれば良いでしょうか?
CallByName メソッドを使って呼び出す分には問題ありません。もしくは、その部分だけを
Option Strict Off 設定の Partial Class に切り出すようにするかですね。
引用返信 編集キー/
■83365 / inTopicNo.5)  Re[4]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (3回)-(2017/03/19(Sun) 14:18:08)



ありがとうございます。

Dim ccc = DirectCast(bbb, Class_Name)
の間違いです

TaskでObject以外の引数を受ける方法は分かったのですが

MultiProgram_run = New Thread(AddressOf Program_runxx) With {.IsBackground = True}
MultiProgram_run.Start(hiki)


という用法でもObject以外の引数を受ける方法があれば教えてください。

それとCallByName メソッドというのは何でしょうか?
これを使ったWshShell オブジェクトの呼び出し方をできれば教えていただけないでしょうか?





引用返信 編集キー/
■83366 / inTopicNo.6)  Re[5]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 魔界の仮面弁士 (1203回)-(2017/03/19(Sun) 15:06:10)
No83365 (惹起 さん) に返信
> MultiProgram_run = New Thread(AddressOf Program_runxx) With {.IsBackground = True}
> MultiProgram_run.Start(hiki)
先ほどと同様に
 Dim t As New Thread(Sub() Program_runxx(hiki)) With {.IsBackground = True}
 t.Start()
では駄目ということでしょうか。もしも ThreadStart デリゲートでは都合が悪いのなら、
素直に ParameterizedThreadStart デリゲートで受け渡すのが妥当かと思います。


> それとCallByName メソッドというのは何でしょうか?
> これを使ったWshShell オブジェクトの呼び出し方をできれば教えていただけないでしょうか?
使用例はヘルプに書かれていますので、それを WshShell オブジェクトに適用してみてください。
全く分からないのであれば、CreateObject でレイトバインド呼び出しにしたりせず、
"Windows Script Host Object Model" を参照設定した上で、素直にアーリーバインドで呼ぶべきかと。

ただし先ほども書きましたが、そもそも VB.NET から WshShell を呼ぶことはお奨めしません。
パフォーマンスも悪いですし、呼び出しの手間もかかるだけでメリットがありません。
マルチスレッド環境からの利用を想定しているのであれば尚の事。
(WshShell は Single Thread Apartment モデルのコンポーネントです)


一応、WshShell によるデスクトップパスの取得コードも書いておきますが、
素直に .NET Framework の標準機能で取得するべきかと思いますよ。


===== .NET Framework でデスクトップのパスを取得するための標準的なコード =====
Dim desktopFolderPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)


===== VB ランタイムを用いてデスクトップのパスを取得するためのコード =====
Dim desktopFolderPath As String = My.Computer.FileSystem.SpecialDirectories.Desktop



===== WshShell を参照設定してデスクトップのパスを取得するコード =====
'要 COM 参照設定 [Windows Script Host Object Model]
Dim wshShell As New IWshRuntimeLibrary.WshShell()
Dim wshFolders As IWshRuntimeLibrary.IWshCollection = wshShell.SpecialFolders
Dim targetName As Object = "Desktop"

Dim desktopFolderPath As String = DirectCast(wshFolders.Item(targetName), String)

'COM コンポーネントの解放処理
System.Runtime.InteropServices.Marshal.ReleaseComObject(wshFolders)
System.Runtime.InteropServices.Marshal.ReleaseComObject(wshShell)


===== CallByName 経由の呼び出しにて WshShell からデスクトップのパスを取得するコード =====
Dim wshShell As Object = CreateObject("WScript.Shell")
Dim wshFolders As Object = CallByName(wshShell, "SpecialFolders", CallType.Get)

Dim desktopFolderPath As String = DirectCast(CallByName(wshFolders, "[DispId=0]", CallType.Get, "Desktop"), String)

'COM コンポーネントの解放処理
System.Runtime.InteropServices.Marshal.ReleaseComObject(wshFolders)
System.Runtime.InteropServices.Marshal.ReleaseComObject(wshShell)
引用返信 編集キー/
■83367 / inTopicNo.7)  Re[6]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (4回)-(2017/03/19(Sun) 15:10:14)
ありがとうございます。

この方法を使えば、マルチスレッドでも
複数の引数を受けることができるのですね。

以前、調べた時は1つしか引数を受けられない、とどこかに書かれてあったのですが
これは間違いでしたか・・・。
 
解決済み
引用返信 編集キー/
■83368 / inTopicNo.8)  Re[7]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (5回)-(2017/03/19(Sun) 15:12:02)
あと、ちなみに

MultiProgram_run = New Thread(Sub() Program_runxx(hiki)) With {.IsBackground = True, .start}

のようにマルチスレッドクラスの作成と実行を
同時に行うことは可能でしょうか?


引用返信 編集キー/
■83369 / inTopicNo.9)  Re[8]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (7回)-(2017/03/19(Sun) 16:26:53)
すいません、
あと、


MultiTask = New Task(Of String())(AddressOf aaa,bbb)

なら、

MultiTask.resultで
返り値を取得することができるのですが
MultiTask = New Task(Of String())(Function() aaa(bbb))
これだと、
ResultはSystem,Threading.Tasks.Taskのメンバーではありません

というエラーが出てしまいます。

どうすれば良いですか?

 
引用返信 編集キー/
■83370 / inTopicNo.10)  Re[9]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (8回)-(2017/03/19(Sun) 16:29:08)
Dim MultiTask as Task
ではなく
Dim MultiTask as Object

とするとうまくいきました

引用返信 編集キー/
■83371 / inTopicNo.11)  Re[10]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (9回)-(2017/03/19(Sun) 16:30:54)
間違いました

option strictがoffの時にはエラー出なくなりました
object宣言しているので
option strictをonにするとエラーになってしまいます

どうすれば良いですか?

引用返信 編集キー/
■83372 / inTopicNo.12)  Re[11]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (10回)-(2017/03/19(Sun) 16:46:44)
Dim MultiTask As Task(Of String())

でうまくいきました

 
引用返信 編集キー/
■83373 / inTopicNo.13)  Re[8]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ Azulean (798回)-(2017/03/19(Sun) 17:02:18)
Web 上のコミュニケーションのレスポンスは基本的に時間がかかるので、じっくりと試行錯誤してからご質問いただいた方が良いかと。
そうでないと、回答の準備をしている間に解決していて、時間を無駄にしてしまう可能性もあるので…。

No83368 (惹起 さん) に返信
> あと、ちなみに
>
> MultiProgram_run = New Thread(Sub() Program_runxx(hiki)) With {.IsBackground = True, .start}
>
> のようにマルチスレッドクラスの作成と実行を
> 同時に行うことは可能でしょうか?

基本的に Thread クラスは生成と実行を同時に実現するメソッドを提供していないので、作成と実行は別々の単位になります。
引用返信 編集キー/
■83374 / inTopicNo.14)  Re[7]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 魔界の仮面弁士 (1204回)-(2017/03/19(Sun) 18:20:13)
No83367 (惹起 さん) に返信
> この方法を使えば、マルチスレッドでも
> 複数の引数を受けることができるのですね。

任意の個数の引数を渡せれば便利かも知れませんが、実際の開発では
「配列」や「自作クラス(匿名型でも可)」を使うことで
複数の情報を 1 つの引数で渡せるので、特に困らないわけです。


> 以前、調べた時は1つしか引数を受けられない、とどこかに書かれてあったのですが

ラムダ式での指定、たとえば「Sub() Program_runxx(hiki)」のような呼び出しだと、
変数 hiki がどのタイミングで評価されるのか分かりにくいという問題もありますので、
当初の通り、素直に Object 型で渡してやるのも一つの手かと思います。
引用返信 編集キー/
■83375 / inTopicNo.15)  Re[8]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 魔界の仮面弁士 (1205回)-(2017/03/19(Sun) 18:32:17)
No83368 (惹起 さん) に返信
> MultiProgram_run = New Thread(Sub() Program_runxx(hiki)) With {.IsBackground = True, .start}
> のようにマルチスレッドクラスの作成と実行を
> 同時に行うことは可能でしょうか?

同時に行うことはできないですね。せいぜい、
 'DirectCast(New Thread(Sub() Program_runxx(hiki)) With {.IsBackground = True}, Thread).Start()
 Dim th As New Thread(Sub() Program_runxx(hiki)) With {.IsBackground = True} : th.Start()
のように、無理矢理一行にまとめるぐらいでしょうか。
引用返信 編集キー/
■83376 / inTopicNo.16)  Re[8]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (11回)-(2017/03/19(Sun) 19:55:11)
ありがとうございます。

非常に勉強になります。

あと、ImageMagickを使うときに

Dim mi As Object = CreateObject("ImageMagickObject.MagickImage")
というようにObject宣言する必要があるのですが、
これもoption strict onでエラーとなってしまいます。

これはどのようにして回避して使えば良いですか?
 
引用返信 編集キー/
■83377 / inTopicNo.17)  Re[9]:
□投稿者/ Azulean (799回)-(2017/03/19(Sun) 22:04:38)
2017/03/19(Sun) 22:06:53 編集(投稿者)

No83376 (惹起 さん) に返信
> Dim mi As Object = CreateObject("ImageMagickObject.MagickImage")
> というようにObject宣言する必要があるのですが、
> これもoption strict onでエラーとなってしまいます。
>
> これはどのようにして回避して使えば良いですか?

1.参照設定で参照して、型をインポートできるのであれば、そうする。
 参照設定→ COM で ImageMagick の参照ができるならそれを。
 これができるのはタイプライブラリがあるときです。
 ImageMagick がタイプライブラリを提供していない場合は、この選択肢はありません。

2.GetType を使った長くなるコードを頑張る。
 以下は遅延バインディングの C# の例ですが、これを参考に VB.NET かつ、ImageMagick の場合に合わせたコードを作っていく感じになりますが…、正直おすすめしません。
 https://urashita.com/archives/1760

3.Option Strict On をあきらめる
 タイプライブラリがなく、遅延バインディングに頼らざる得ないのであれば、Option Strict Off にした方が生産性が高いです。
 それが必要なところだけ、クラスを分けるなど、工夫してください。
引用返信 編集キー/
■83378 / inTopicNo.18)  Re[9]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 魔界の仮面弁士 (1206回)-(2017/03/19(Sun) 23:52:23)
No83376 (惹起 さん) に返信
> これはどのようにして回避して使えば良いですか?
先の回答と一緒ですよ。基本的には参照設定してアーリーバインドとするか、
レイトバインドなら CallByName で対処するかです。


> あと、ImageMagickを使うときに
> Dim mi As Object = CreateObject("ImageMagickObject.MagickImage")
> というようにObject宣言する必要があるのですが、
> これもoption strict onでエラーとなってしまいます。

ImageMagickObject.dll (ImageMagic Object x.x Type Library)を参照設定して、
 Dim mi As New ImageMagickObject.MagickImage()
のように、固有の型で処理するようにします。

もしくは先にも書いたように CallByName を使うかですね。

いずれの方法を使うにしても、使用したオブジェクトの解放処理のために
Marshal.ReleaseComObject メソッドでの後始末が必要です。

※ImageMagickObject のスレッドモデルについては未確認。
引用返信 編集キー/
■83400 / inTopicNo.19)  Re[10]: これらの引数で呼び出されるアクセス可能なNewがないため・・
□投稿者/ 惹起 (12回)-(2017/03/21(Tue) 10:22:24)
No83378 (魔界の仮面弁士 さん) に返信
> ■No83376 (惹起 さん) に返信
解決しました。ありがとうございます。

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ